NSNotificationCenter 方法 postNotification 中的对象参数

Object parameter in method postNotification of NSNotificationCenter

在我的 iOS 应用程序中,我发布了一个 NSNotification 并在主线程中的一个 UIView 中捕获它。我想随通知一起传递额外信息。为此,我使用了 userInfo NSNotification 的字典。

[[NSNotificationCenter defaultCenter] postNotificationName:@"NotifyValueComputedFromJS" object:self userInfo:@{@"notificationKey":key,@"notificationValue":value,@"notificationColor":color,@"notificationTimeStamp":time}];

键、值、颜色和时间是局部变量,其中包含我需要传递的值。在 UIView 中,我为此通知添加了观察者,并且我正在使用 notification.userInfo 来获取这些数据

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:@"NotifyValueComputedFromJS" object:nil];

-(void)receiveNotification:(NSNotification *)notification
{
     if ([notification.userInfo valueForKey:@"notificationKey"]!=nil && [[notification.userInfo valueForKey:@"notificationKey"] isEqualToString:self.notificationKey] && [notification.userInfo valueForKey:@"notificationValue"]!=nil) {
         [self updateLabelWithValue:[notification.userInfo valueForKey:@"notificationValue"]];
     }
}

此通知的发布频率是一秒4次。我也在主线程中做一些动画。我在这里面临的问题是我的 UI 滞后。 UI 会以巨大的延迟响应滚动事件或触摸事件(我遇到过甚至 1 到 2 秒的延迟)。经过一些研究,我开始知道 NSDictionary 体积庞大,如果在主线程中使用会导致延迟。有没有其他方法可以通过 NSNotification 传递我的数据?

我试过另一种方法。我创建了一个自定义 NSObject class 来保存我想要的数据,我将它作为 postNotification 方法的对象参数传递。

[[NSNotificationCenter defaultCenter] postNotificationName:@"NotifyValueComputedFromJS" object:customDataObject userInfo:nil];

这里customDataObject是我的自定义实例NSObjectclass。我知道该参数是通知的发送者(通常是自己)。如果我将自定义对象作为参数发送,这是一种错误的方法吗?

也许你可以使用 - addObserverForName:object:queue:usingBlock:

并使用非主队列来执行块以减少延迟。另外,观察者不应该添加到 UIViewController 中,而不是 UIView 中吗?

正如 BobDave 所提到的,关键是在主 UI 线程以外的某个线程上发送通知。这可以通过 dispatch_async 或队列来完成。

此行为的典型模式是发件人:

-(void)sendDataToObserver {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:@"NotifyValueComputedFromJS" object:customDataObject userInfo:userInfo:@{@"notificationKey":key,@"notificationValue":value,@"notificationColor":color,@"notificationTimeStamp":time}];
    });
}

和接收者(注意:因为保留循环而自我弱化):

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

-(void)receiveNotification:(NSNotification *)notification {
     if ([notification.userInfo valueForKey:@"notificationKey"]!=nil && [[notification.userInfo valueForKey:@"notificationKey"] isEqualToString:self.notificationKey] && [notification.userInfo valueForKey:@"notificationValue"]!=nil) {
         __weak typeof (self) weakSelf = self;

         dispatch_async(dispatch_get_main_queue(), ^{
             [weakSelf updateLabelWithValue:[notification.userInfo valueForKey:@"notificationValue"]];
         });
     }
}