首页 > 代码库 > 关于block 中 何时使用 __weak/__block MyViewController * weakSelf 分析
关于block 中 何时使用 __weak/__block MyViewController * weakSelf 分析
说到block .想听我废话下它的基础。
block 是一个闭包函数。所谓闭包就是
引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。
oc 中 block 默认创建后 分配在栈中。。当向其 发送 copy 消息后 被移到堆上。 防止被释放。
由上面定义可以看出 block 会 保留在它所引用到的 一切变量。
__block 参数是什么? 修饰变量时 做了什么?
它是一个存储类型。 block 中体现为 不会保留 这样的变量。 同时 你可以在block 中修改(读写)它。
何时该用 __weak/__block MyViewController *
weakSelf ??
分析下面两个例子。
1,执行一个动画
[ UIView animateWithDuration: 0.5 animations: ^ { self.someView . alpha = 0 ; } completion: ^ ( BOOL finished ) { [ self.someView removeFromSuperView ]; }];
不用block 是这样的。- ( void ) fadeOutView {
[ UIView beginAnimations ]; [ UIView setAnimationDuration: 0.5 ]; [ UIView setAnimationDelegate: self ]; [ UIView setAnimationDidStopSelector: @selector ( animationDidStop:finished:context: )]; self.someView . alpha = 0 ; [ UIView commitAnimations ]; } - ( void ) animationDidStop: ( NSString * ) animationID finished: ( NSNumber * ) finished context: ( void * ) context { [self. someView removeFromSuperView ]; }
2, 使用 一个 通知。
- ( void ) setupNotifications { [[ NSNotificationCenter defaultCenter ] addObserverForNotificationName: MyWhizBangNotification object: nil queue: [ NSOperationQueue mainQueue ] block: ^ ( NSNotification * notification ) { //reload该表以显示新的嗖bangs [ self . tableView reloadData ]; }]; } - ( void ) dealloc { [[ NSNotificationCenter defaultCenter ] removeObserver: self ]; [ super dealloc ]; }
不使用block 是这样的。
- ( void ) setupNotifications { [[ NSNotificationCenter defaultCenter ] addObserver: self selector: @selector ( onWhizBang: ) name: MyWhizBangnotification object: nil ]; } - ( void ) onWhizBang: ( NSNotification * ) notification { //重新加载该表以显示新的嗖bangs [ self . tableView reloadData ]; } - ( void ) dealloc { [[ NSNotificationCenter defaultCenter ] removeObserver: self ]; [ super dealloc ]; }
对于前者是没有问题的, 后者是 有问题的。
来分析下 后者:
首先这里有 三个对象。
self .NSNotificationCenter . block.
是的block 也是对象。
NSNotificationCenter 强引用着 self .
self 强引用着 block .
block 强引用着 self .
这里NSNotificationCenter 和 self 关系没有问题。
当我们在self 的 dealloc 中
[[ NSNotificationCenter defaultCenter ] removeObserver: self ];
将会 释放 block 对象。block 释放它引用的变量 self. 构成引用循环。
第一个例子为什么不会?
也是三个对象
self . someView . block.
self 强引用view
block 强引用 view
而这里 block 是被 view的拥有者 self 强引用着。
这里并没有循环引用。 self 释放 时 block 会释放 view 。
所以对于这种情况 。解放办法是 在block 中不让它强引用 self 。如题使用
__block MyViewController * weakSelf 和__weak MyViewController * weakSelf
可以达到一样效果。
参考文章:http://benscheirman.com/2012/01/careful-with-block-based-notification-handlers/
关于block 中 何时使用 __weak/__block MyViewController * weakSelf 分析
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。