NSNotificationCenter使用block方式的一点注意事项
2012-06-04 17:13 v2m 阅读(5065) 评论(0) 编辑 收藏 举报非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环境中就用第一种书写方式好了。
这些只是个人的理解与代码测试,如果有更恰当的理解方式与说明,请留言告诉我。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!