2

我创建了一个子类UIView

BeneficialsFormView *view = [[BeneficialsFormView alloc] init];
view.alpha = 0;
view.delegate = self;

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

委托调用是显示UIView并返回一个我用来禁用背景触摸的 UIView(只是一个具有黑色背景颜色和减少 alpha 的 UIView)。

在 subclassedUIView中,我添加了键盘通知:

-(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
}

我尝试删除NSNotificationsin dealloc

-(void)dealloc {
    DLog(@"fired");

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

问题是在以下dealloc情况下被解雇awakeFromNib

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

它们都在 0.1 秒内发射。子类的UIView行为完全符合我的要求;它显示,它的所有内容都有效,我可以removeFromSuperview解决问题。

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

我正在使用 ARC。

我究竟做错了什么?

编辑:

发现我做错了什么:

-(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显示创建的对象时被释放。

我怎样才能解决这个问题?还是我在做一些根本错误的事情并在时空连续体中造成撕裂?

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>>
4

2 回答 2

3

你把事情弄得太复杂了。简单一点:

1.) 加载基础视图

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

3.)如果是这样,只需将渐变叠加为子视图。当用户按下按钮离开视图时,移除 NSNotificationCenter 观察者。不要在dealloc中删除它。它经常被延迟,你会看到同样的问题发生。

于 2013-06-12T23:54:43.017 回答
1

我正在寻找类似问题的答案,我发现了两种可以添加和删除观察者的方法。只是为了显示更新的 API,供正在寻找它的人使用。

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

- (void)willMoveToWindow:(UIWindow *)newWindow {
    if (newWindow == nil) {
        [[NSNotificationCenter defaultCenter] removeObserver:
                                                        name:
                                                      object:];
     }
}

下面的方法在其 window 属性设置后立即被调用。

-(void)didMoveToWindow {
        if (self.window) {
            [[NSNotificationCenter defaultCenter] addObserver:
                                                     selector: 
                                                         name:
                                                       object:];
        }
    }
于 2015-01-13T06:18:01.250 回答