【问题标题】:NSNotificationCenter addObserver being ignoredNSNotificationCenter addObserver 被忽略
【发布时间】:2014-04-18 13:40:37
【问题描述】:

在使用 XCode 5.1(和 CorePlot 1.4)之前,两个对象在接收 NSNotifications 之前工作得很好。但是,使用 XCode 5.1.1 (Coreplot 1.5) 我发现如果 addObserver 调用在 init 方法内,它实际上不会被注册(仅对于这两个类,它在不同的类别)。我什至在通话前后都添加了NSLog,以确保代码仍然有效。这两个对象都被它们的共享父级强烈引用,并且它们的父级会毫无问题地接收必要的通知。而且,我在dealloc 中有一个NSLog,其中removeObserver 是-它不会提前调用,因为对象被正确保留。

//The object is a CorePlot CPTGraphHostingView
- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        //other code setting up a few private ivar primitive arrays and values

        //this is where the call was (there are actually 3 Observer calls made)
        [[NSNotificationCenter defaultCenter]
        addObserver: self
        selector: @selector(recordUpdated)
        name: @"recordUpdated"
        object: nil];

        //then this is called before the end
        [self prepareGraph];

        //this is where I moved it
        [self startListening];
    }
    return self;
}

同样,自从我上次使用 XCode 5.1(和 CorePlot 1.4)编译它以来,发送通知的对象或这两个类的代码没有任何改变。并且在父级的init 中使用了相同的调用,并且运行良好。昨晚我唯一的解决方案是将addObserver 调用重构为一个新方法,并在init 末尾调用该方法。

但是,我不明白为什么这是必要的。谁能想到将addObserver 放在init 中间会被“忽略”的原因,但是当在init 调用的另一个方法中时,它可以工作吗?

编辑和注释:

我添加了更多代码来显示初始化。我还添加了注释,它是 CorePlot 的图形视图,CorePlot 最近也更新到了 1.5(我忘记了)——这可能是问题的根源。

lead_the_zeppelin 建议重新分配它似乎是可能的。但是,从 NSNotificationCenter 到 -now-dealloc'd 对象的调用不会使程序崩溃(注意,不调用 dealloc - 我在那里有一个NSLog)?我可以通过在init 中打印对象实例字符串来轻松测试这一点,然后再打印。我昨晚确实测试了这个,要求提供实例,但我认为我没有将那个位复制到init

【问题讨论】:

  • 这似乎与您的 init 方法中发生的其他事情有关。也许发帖可以让我们提供帮助?
  • 完成。这样做让我意识到我最近也更新了 CorePlot。
  • 只是为了检查一下,您在recordUpdated 方法中有一个NSLog(或断点),是的,可以检查它是否被调用? (我知道这听起来很明显,但它很容易做到!)
  • 你也可以发布发送通知的代码吗:)
  • 您在使用 ARC 吗?您可以尝试在启用 NSZombies 的情况下运行,以查看是否发生了提前释放。

标签: ios objective-c core-plot nsnotificationcenter addobserver


【解决方案1】:

每当您设置托管图或collapsesLayers 属性时,Core Plot 托管视图都会将自己移除为所有通知的观察者。如果您希望我们修复它,请在issue tracker 上发布错误报告。

与此同时,在您设置图表后添加您的观察者。

【讨论】:

  • 我没想过要涉足 CorePlot 源代码。但是,是的,它在updateNotifications 方法下。我还注意到dealloc 也已经调用了removeObserver。我看到有两种方法可以调用它:setHostedGraphsetCollapsesLayers。我想我会把它作为一个错误发布,因为我想知道如何能够可靠地继承CPTGraphHostingView,而不必在每次修改图形结构时定期重新addObserver
【解决方案2】:

在您订阅通知中心后,self 可能会被重新分配。可以把代码移到

-(void)awakeFromNib
{
    [[NSNotificationCenter defaultCenter]addObserver: self  selector:@selector(recordUpdated) name:@"recordUpdated" object:nil];
}

或者可能是 -viewDidLoad

【讨论】:

  • 我添加了一些额外的代码和注释。这些不是 UIView,所以它们不会从 Nibs 中唤醒。
  • @Adam -prepareGraph 是做什么的?
  • Core Plot 托管视图是 UIView 的子类。因此,您的子类也是。
  • @lead_the_zeppelin,prepare graph 只是做 CorePlot 的事情,比如定义图形轴和设置绘图空间。
  • @EricSkroch,你可能是对的,但它仍然没有回答 - 为什么 - 它以它的方式失败。我已经可以让它做一些不同的事情,我可以把它移到viewDidLoad(假设它被调用),但它应该在init中工作。
猜你喜欢
  • 2014-07-25
  • 2014-11-22
  • 2012-12-07
  • 1970-01-01
  • 2015-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多