NSNotificationCenter, блоки и ivar типа SEL: не могу заставить его работать - PullRequest
1 голос
/ 12 августа 2011

Я пытаюсь следующее:

Всякий раз, когда токен OAuth изменяется, я хочу обновить некоторые из моих контроллеров представления. Контроллеры представления, которые я хочу обновить, все наследуют от контроллера представления. Этот контроллер представления будет прослушивать уведомления всякий раз, когда установлен новый токен доступа или когда маркер доступа очищен. Всякий раз, когда токен доступа установлен или очищен, я хочу установить селектор на метод, который должен выполняться после отображения контроллера представления (т. Е. На -viewWillAppear:).

Каким-то образом блоки внутри addObserverForName:object:queue:usingBlock:, похоже, не вызывают. Я не могу заставить это войти даже. Из-за этого селекторы никогда не меняются. Из того, что я прочитал, используя атрибут __block на иваре, следует разрешить изменение ивара внутри блока.

@interface SDViewController ()
- (void)reloadData;
- (void)clearData;
@end


@implementation SDViewController 
{
   __block SEL selectorOnViewWillAppear;
}

- (id)initWithDataSource:(id <SDViewControllerDataSource>)dataSource
{
   self = [super init];
   if (self) 
   {
      selectorOnViewWillAppear = @selector(reloadData);
   }
   return self;
}

- (void)viewDidLoad 
{
   NSLog(@"view did load");

   [super viewDidLoad];

   [[NSNotificationCenter defaultCenter] addObserverForName:kAccessTokenChangedNotification object:self queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *note) {
      NSLog(@"selector: test1");
      selectorOnViewWillAppear = @selector(reloadData);
   }];
   [[NSNotificationCenter defaultCenter] addObserverForName:kAccessTokenClearedNotification object:self queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *note) {
      NSLog(@"selector: test2");
      selectorOnViewWillAppear = @selector(clearData);
   }];
}

- (void)viewWillAppear:(BOOL)animated
{
   [super viewWillAppear:animated];

   if (selectorOnViewWillAppear) 
      [self performSelector:selectorOnViewWillAppear];
}

- (void)reloadData
{
   NSLog(@"reloadData");
   selectorOnViewWillAppear = nil;
}

- (void)clearData 
{
   NSLog(@"clearData");
   selectorOnViewWillAppear = nil;
}

@end

1 Ответ

0 голосов
/ 15 августа 2011

Исправлено путем изменения кода наблюдателя:

[[NSNotificationCenter defaultCenter] 
   addObserverForName:kAccessTokenClearedNotification 
   object:self 
   queue:[NSOperationQueue currentQueue] 
   usingBlock:^(NSNotification *note) {
      NSLog(@"selector: test2");
      selectorOnViewWillAppear = @selector(clearData);
   }];

К этому:

[[NSNotificationCenter defaultCenter] 
   addObserverForName:kAccessTokenClearedNotification 
   object:nil 
   queue:[NSOperationQueue currentQueue] 
   usingBlock:^(NSNotification *note) {
      NSLog(@"selector: test2");
      selectorOnViewWillAppear = @selector(clearData);
   }];

Документация Apple связанак этому вопросу находится здесь .Объект в методе -addObserverForName:object:queue:usingBlock: должен быть объектом, который генерирует уведомления.Установка объекта на nil исправила проблему.

...