开发者

NSNotificationCenter, blocks and ivar of type SEL: can't get it to work

开发者 https://www.devze.com 2023-03-27 21:21 出处:网络
I\'m trying the following: Whenever an OAuth token changes, I want to update some of my view controllers. The view controllers I want to update all inherit from a view controller. This view controlle

I'm trying the following:

Whenever an OAuth token changes, I want to update some of my view controllers. The view controllers I want to update all inherit from a view controller. This view controller will listen for notifications whenever a new access token is set or whenever the access token is cleared. Whenever the access token is set or cleared, I want to set a selector to a method that should be executed once the view controller will be displayed (i.e. on -viewWillAppear:).

Somehow the blocks inside the addObserverForName:object:queue:usingBlock: don't seem to get called. I can't get it to log even. Because of this the selectors never change. From what I've read using the __block attribute on an ivar should allow the ivar to be changed from within a 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(@开发者_JAVA技巧"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


Fixed it by changing the observer code from this:

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

To this:

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

The Apple documentation related to this issue is found here. The object in the -addObserverForName:object:queue:usingBlock: method should be the object that generates the notifications. Setting the object to nil fixed the issue.

0

精彩评论

暂无评论...
验证码 换一张
取 消