0

我有一个 iPad 应用程序,它使用一个注册“UIScreenDidConnectNotification”的专有库对象。有时,这个对象在幕后被释放和重新分配。因为它在图书馆中,所以我无法确保它正确地删除了这个观察者。

有没有办法让我手动删除特定通知的所有/任何观察者(即 UIScreenDidConnectNotification),而无需访问已注册的对象。这将阻止应用程序将消息发送到已释放的对象。

更新:这是解决我的问题的最简单方法。我希望我能做得更好,但生命太短暂了。#导入 #导入

@interface NSNotificationCenter (AllObservers)
@end

@implementation NSNotificationCenter (AllObservers)

// This function runs before main to swap in our special version of addObserver
+ (void) load
{
    Method original, swizzled;
    original = class_getInstanceMethod(self, @selector(addObserver:selector:name:object:));
    swizzled = class_getInstanceMethod(self, @selector(swizzled_addObserver:selector:name:object:));

    method_exchangeImplementations(original, swizzled);


// This function runs before main to swap in our special version of addObserver
+ (void) load
{
    Method original, swizzled;
    original = class_getInstanceMethod(self, @selector(addObserver:selector:name:object:));
    swizzled = class_getInstanceMethod(self, @selector(swizzled_addObserver:selector:name:object:));

    method_exchangeImplementations(original, swizzled);
}

/*
    Use this function to remove any unwieldy behavior for adding observers
 */
- (void) swizzled_addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender
{
    NSString *notification = [[NSString alloc] initWithUTF8String: "UIScreenDidConnectNotification" ];

    // It's a hack, but I just won't allow my app to add this type of notificiation
    if([notificationName isEqualToString: notification])
    {
        printf("### screen notifcation added for an observer: %s\n", [notificationSender UTF8String] );
    }
    else
    {
        // Calls the original addObserver function
        [self swizzled_addObserver:notificationObserver selector:notificationSelector name:notificationName object:notificationSender];
    }   
}
4

2 回答 2

2

因为它在图书馆中,所以我无法确保它正确地删除了这个观察者。

如果对象是在库中创建的,则删除该对象不是您的责任。如果库正在释放对象而不将其从通知中心删除,那么这是库中的一个明显错误。

有没有办法让我手动删除特定通知的所有/任何观察者......而无需访问已注册的对象。

NSNotificationCenter的 API 中没有任何内容可以让您这样做。恰恰相反,事实上——让你删除观察者的方法都需要一个指向特定对象的指针。

于 2013-07-17T21:22:51.497 回答
1

我同意 Caleb 的两点:执行此任务不是您的责任,API 中没有任何内容支持它。

但是...如果您出于某种原因想要破解某些东西来执行此任务,请参阅此线程:如何检索所有 NSNotificationCenter 观察者?

该线程的选定答案具有一个类别NSNotificationCenter,允许您检索给定通知名称的所有观察者。同样,虽然不推荐这样做。

于 2013-07-17T21:27:10.567 回答