Параметр объекта в методе postNotification 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 раза в секунду. Я делаю некоторые анимации также в основном потоке. Проблема, с которой я сталкиваюсь, заключается в том, что мой пользовательский интерфейс отстает. Пользовательский интерфейс будет реагировать на события прокрутки или касания с огромной задержкой (я сталкивался с задержкой даже в 1-2 секунды). После некоторых исследований я узнал, что NSDictionary громоздкий и вызовет отставание, если используется в основном потоке. Есть ли другой способ передать свои данные через NSNotification?

Я попробовал другой способ. Я создал собственный класс NSObject для сохранения нужных мне данных и передаю его в качестве параметра объекта метода postNotification.

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

Здесь customDataObject — это экземпляр моего пользовательского класса NSObject. Я знаю, что параметр предназначен для отправителя уведомления (обычно это будет сам). Это неправильный подход, если я отправляю пользовательский объект в качестве параметра?


person Rasitha A K    schedule 25.05.2016    source источник


Ответы (2)


Как упомянул БобДэйв, ключевым моментом является отправка уведомления в какой-либо поток, отличный от основного потока пользовательского интерфейса. Это можно сделать с помощью 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"]];
         });
     }
}
person Lytic    schedule 01.02.2017
comment
Большое спасибо @Lytic. Спасибо за пример кода :) - person Rasitha A K; 30.03.2017

Возможно, вы могли бы использовать - addObserverForName:object:queue:usingBlock:

и использовать неосновную очередь для выполнения блока, чтобы уменьшить задержку. Кроме того, не следует ли добавлять наблюдателя в UIViewController, а не в UIView?

person BobDave    schedule 17.08.2016