关于block 中 何时使用 __weak/__block MyViewController * weakSelf 分析
来源:互联网 发布:雷蒙德钱德勒 知乎 编辑:程序博客网 时间:2024/06/05 18:08
说到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
可以达到一样效果。
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/
转载自:http://www.cnblogs.com/tangbinblog/p/4033365.html
0 0
- 关于block 中 何时使用 __weak/__block MyViewController * weakSelf 分析
- iOS block何时可以不使用weakSelf
- ARC下Block何时会从栈自动被复制到推, 以及__block和__weak的使用问题
- __block与__weak的区别,block使用注意点
- Block中weakSelf的使用
- __block __weak 的使用讲解
- OC的Block中使用weakSelf/strongSelf
- 在block循环引用的问题中__block和 __weak 的选择
- 【IOS学习】iOS——Block中 __block、__weak 、typeof、define等词的小解释
- iOS面试题(2.)关于在block中使用weakSelf的讨论
- __weak && __block
- __block __weak
- 关于__block和__weak的详解
- iOS之__block和__weak使用
- iOS之__block、__strong和__weak使用
- __block 与 __weak的区别与使用
- 关于block 循环引用 weakSelf
- 关于block 循环引用 weakSelf
- for()循环里面定义变量
- Android 动画效果 --Animation 动画(讲解了所有的Android动画效果,是一个值得收藏的帖子)
- Retrieving the COM class factory for component with CLSID {C1F400A0-3F08-11D3-9F0B-006008039E37} fai
- 一个应用实例详解卡尔曼滤波及其算法实现
- 异常处理的基本过程
- 关于block 中 何时使用 __weak/__block MyViewController * weakSelf 分析
- 【程序运行时找不到库文件】nginx: error while loading shared libraries: libpcre.so.1
- linux内核中的xx_initcall和module_init实现机制(linux3.1.0)
- 系统学习hbase
- CUDA学习(3)——运行黑屏后恢复
- mint 下fictx输入法
- nmon 介绍和使用
- Android动画之translate(位移动画)
- Jasper Reports Development's Shoulds and Shouldn'ts