码迷,mamicode.com
首页 > 其他好文 > 详细

关于block 中 何时使用 __weak/__block MyViewController * weakSelf 分析

时间:2014-10-18 18:11:14      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:http   io   ar   使用   for   sp   on   问题   ad   

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

标签:http   io   ar   使用   for   sp   on   问题   ad   

原文地址:http://www.cnblogs.com/tangbinblog/p/4033365.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!