简体   繁体   English

在dealloc之前观察并删除类别中的NSNotification

[英]Observe and remove an NSNotification within a category before dealloc

I am currently observing a notification throughout the life of an object in a category . 我目前正在观察一个类别中对象的整个生命周期的通知。 However, I am swizzling the dealloc method to have a spot to remove the observation. 但是,我正在调动dealloc方法以获得删除观察的位置。 This feels bad and I am uncomfortable with it, additionally I am running into problems. 这感觉不好,我对它感到不舒服,另外我遇到了问题。

Does anyone have any ideas how I can stop observing the notification just before the object will be deallocated within a category ? 有没有人有任何想法如何在一个类别中取消分配对象之前停止观察通知?

The best way to run code at the deallocation of an object for which you can't override dealloc is by using associated objects . 在释放无法覆盖dealloc的对象时运行代码的最佳方法是使用关联对象

The object that you associate to will release its strongly-held associated objects when it deallocates. 与其关联的对象将在取消分配时释放其强关联对象。 As long as that is the only owner, the associated object's dealloc will then be called. 只要那是唯一的所有者,就会调用关联对象的dealloc Using a class you control for the associated object, that's your entry point. 使用您为关联对象控制的类,这是您的入口点。

I've got a demonstration of using this trick to deregister for KVO in a GitHub repo https://github.com/woolsweater/UIViewController-WSSDataBindings 我有一个演示,使用这个技巧在GitHub回购中取消注册KVO https://github.com/woolsweater/UIViewController-WSSDataBindings

The controller associates a helper object to itself: 控制器将辅助对象与自身关联:

- (void)WSSBind:(NSString *)bindingName
   toObject:(id)target
withKeyPath:(NSString *)path
{
    WSSBinding * binding = [WSSBinding bindingWithBoundName:bindingName
                                                   onObject:self
                                                  toKeyPath:path
                                                   ofObject:target];

    // Attach the binding to both target and controller, but only make it
    // owned by the target. This provides automatic deregistration when the
    // target is destroyed, and allows the controller to unbind at will.
    // Disregard the target and bound path for the key to allow mirroring
    // Cocoa's unbind: method; this is simplest for the controller.
    NSUInteger key = [self WSSAssociateKeyForBinding:bindingName];
    objc_setAssociatedObject(target, (void *)key, binding,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(self, (void *)key, binding,
                             OBJC_ASSOCIATION_ASSIGN);
}

And the WSSBinding class implements dealloc to remove the observer that's been set up elsewhere. 并且WSSBinding类实现dealloc以移除在其他地方设置的观察者。 You can do the same for your NSNotification registration. 您可以为NSNotification注册执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM