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.
精彩评论