首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIView中的NSNotifications和removeObserver

UIView中的NSNotifications和removeObserver
EN

Stack Overflow用户
提问于 2013-06-13 04:46:36
回答 2查看 2.2K关注 0票数 2

我创建了一个子类UIView

代码语言:javascript
复制
BeneficialsFormView *view = [[BeneficialsFormView alloc] init];
view.alpha = 0;
view.delegate = self;

view.screenView = [self.delegate displayEntityForm:view];

委托调用是为了显示UIView并返回一个我用来禁用背景触摸的UIView (只是一个黑色背景色和简化的alpha的UIView )。

在子类化的UIView中,我添加了键盘通知:

代码语言:javascript
复制
-(void)awakeFromNib {
    DLog(@"fired");

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardEvent:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardEvent:) name:UIKeyboardWillHideNotification object:nil];

    // UI Code
}

我尝试删除dealloc中的NSNotifications

代码语言:javascript
复制
-(void)dealloc {
    DLog(@"fired");

    [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:UIKeyboardWillShowNotification];
    [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:UIKeyboardWillHideNotification];
}

问题是在awakeFromNib之后立即触发dealloc

代码语言:javascript
复制
2013-06-12 15:37:39.260  DEBUG | -[BeneficialsFormView init] | fired
2013-06-12 15:37:39.287  DEBUG | -[BeneficialsFormView awakeFromNib] | fired
2013-06-12 15:37:39.339  DEBUG | -[BeneficialsFormView dealloc] | fired

他们都是以.1秒的速度发射的。子类化的UIView的行为完全如我所愿;它显示,它的所有内容都可以工作,并且我可以removeFromSuperview w/out问题。

我假设当子类UIView的所有引用都达到0时,dealloc会触发?

我正在使用ARC。

我做错了什么?

编辑:

找出我做错了什么:

代码语言:javascript
复制
-(id)init {
    DLog(@"fired");
    DLog(@"self: %@",self);

    self = [super init];

    if (self) {
        self = [[[NSBundle mainBundle] loadNibNamed:@"BeneficialsFormView" owner:self options:nil] objectAtIndex:0];
    }

    return self;
}

因此,我使用init方法创建视图,该方法加载xib文件。awakeFromNib被触发,然后我用我的init文件创建的对象失去引用,并在显示从awakeFromNib创建的对象时被释放。

我该如何解决这个问题呢?还是我做了一些根本错误的事情,并在时空连续体中造成了撕裂?

代码语言:javascript
复制
2013-06-12 18:15:33.957  DEBUG | -[BeneficialsFormView init] | fired
2013-06-12 18:15:33.959  DEBUG | -[BeneficialsFormView init] | self: <BeneficialsFormView: 0x1f0b1d50; frame = (0 0; 0 0); transform = [0, 0, 0, 0, 0, 0]; alpha = 0; opaque = NO; layer = (null)>

2013-06-12 18:15:33.988  DEBUG | -[BeneficialsFormView awakeFromNib] | fired
2013-06-12 18:15:33.989  DEBUG | -[BeneficialsFormView awakeFromNib] | self: <BeneficialsFormView: 0x1e58da60; frame = (0 0; 350 400); autoresize = RM+BM; layer = <CALayer: 0x1e5c60f0>>

2013-06-12 18:15:34.044  DEBUG | -[BeneficialsFormView dealloc] | fired
2013-06-12 18:15:34.045  DEBUG | -[BeneficialsFormView dealloc] | self: <BeneficialsFormView: 0x1f0b1d50; frame = (0 0; 0 0); layer = <CALayer: 0x1f0d4830>>
EN

回答 2

Stack Overflow用户

发布于 2013-06-13 07:54:43

你把事情搞得太复杂了。简单一点就行了:

1.)加载基础视图

2.)检查是否需要显示视图以禁用背景触摸的条件

3.)如果是这样,只需将渐变作为子视图叠加即可。当用户按下按钮离开视图时,移除NSNotificationCenter观察者。Do NOT remove it it dealloc.它经常被延迟,您将看到同样的问题发生。

票数 3
EN

Stack Overflow用户

发布于 2015-01-13 14:18:01

我正在寻找类似问题的答案,我找到了两种方法,我们可以添加和删除观察者。只是为了显示更新的API,为他们正在寻找这一点。

这是在将视图添加到窗口之前调用的。当视图从其窗口中移除时,它也将被调用。

代码语言:javascript
复制
- (void)willMoveToWindow:(UIWindow *)newWindow {
    if (newWindow == nil) {
        [[NSNotificationCenter defaultCenter] removeObserver:
                                                        name:
                                                      object:];
     }
}

方法在设置其窗口属性后立即调用。

代码语言:javascript
复制
-(void)didMoveToWindow {
        if (self.window) {
            [[NSNotificationCenter defaultCenter] addObserver:
                                                     selector: 
                                                         name:
                                                       object:];
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17075047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档