非arc環境中
1。可以正常dealloc釋放
id observer; -(void)back { [[NSNotificationCenter defaultCenter] removeObserver:observer]; [self.navigationController popViewControllerAnimated:YES]; } - (void)viewDidLoad { [super viewDidLoad]; observer = [[NSNotificationCenter defaultCenter] addObserverForName:kPopNotice object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* note){ [self back]; }]; }
2.這樣也可以正常釋放
- (void)viewDidLoad
{
[super viewDidLoad];
__block OtherViewController* ovc = self;
observer = [[NSNotificationCenter defaultCenter] addObserverForName:kPopNotice object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* note){
// 直接用self就不可以
[ovc.navigationController popViewControllerAnimated:YES];
}];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:observer];
[super dealloc];
}
如果在dealloc的時候不removeObserver:observer,那么[NSNotificationCenter defaultCenter]仍然會保留這個observer,當再次post這個kPopNotice消息時,會繼續調用block里面的方法,從而出錯。而且[[NSNotificationCenter defaultCenter] removeObserver:self];也不會清除掉block方式注冊的方法。
1與2的區別在於,1是主動的removeObserver,2是在dealloc中才removeObserver。2中需要能正確的進去dealloc,那么就不能在block中使用self本身。
3. 這樣做無所謂,一樣釋放
self.array = [[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5",@"6", nil] retain]; [array enumerateObjectsUsingBlock:^(id obj,NSUInteger idx,BOOL *stop) { self.title = (NSString*)obj; if (idx == 3) { *stop = YES; } }];
雖然array明顯沒有釋放,但是最后還是調用了dealloc,成功釋放。
綜上,在非arc環境下,如果是[NSNotificationCenter defaultCenter]的block里面使用self,一定要用__block SELFTYPE* tmp = self;然后在block里面用tmp代替self,並且要在最后移除這個observer(而不是self)才算是安全的使用方法。
那么arc的環境中呢?
1.一種比較簡單的寫法
__weak OtherViewController* ovc = self; ovc = self; observer = [[NSNotificationCenter defaultCenter] addObserverForName:kPopNotice object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* note){ [ovc.navigationController popViewControllerAnimated:YES]; }];
即使dealloc中不removeObserver也沒有關系,反正ovc已經只想nil了(weak修飾)
2.如果上面的block中的ova換成self,那么將導致retain cycle
3.如果1中的block中的函數換成 [self back],那么,那么,會出現這樣的情況
每次退出(pop)的時候沒有dealloc,但是再次進入這個頁面(push,當然是重新生成的一個),會調用dealloc,奇了個怪的。[ovc back]很正常。
綜上,在arc環境中就用第一種書寫方式好了。
這些只是個人的理解與代碼測試,如果有更恰當的理解方式與說明,請留言告訴我。
