说到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