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

本文深入探讨了Objective-C中Block的概念及其实现原理,包括闭包的特点、内存管理方式以及如何避免循环引用等问题。
说到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/

转载自:http://www.cnblogs.com/tangbinblog/p/4033365.html

MATLAB主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性内容概要:本文主要介绍了一种在MATLAB环境下实现的主动噪声和振动控制算法,该算法针对较大的次级路径变化具有较强的鲁棒性。文中详细阐述了算法的设计原理与实现方法,重点解决了传统控制系统中因次级路径动态变化导致性能下降的问题。通过引入自适应机制和鲁棒控制策略,提升了系统在复杂环境下的稳定性和控制精度,适用于需要高精度噪声与振动抑制的实际工程场景。此外,文档还列举了多个MATLAB仿真实例及相关科研技术服务内容,涵盖信号处理、智能优化、机器学习等多个交叉领域。; 适合人群:具备一定MATLAB编程基础和控制系统理论知识的科研人员及工程技术人员,尤其适合从事噪声与振动控制、信号处理、自动化等相关领域的研究生和工程师。; 使用场景及目标:①应用于汽车、航空航天、精密仪器等对噪声和振动敏感的工业领域;②用于提升现有主动控制系统对参数变化的适应能力;③为相关科研项目提供算法验证与仿真平台支持; 阅读建议:建议读者结合提供的MATLAB代码进行仿真实验,深入理解算法在不同次级路径条件下的响应特性,并可通过调整控制参数进一步探究其鲁棒性边界。同时可参考文档中列出的相关技术案例拓展应用场景。
你提供的这两个宏定义: ```objective-c /** defines a weak `self` named `__weakSelf` */ #define TPWeakSelf TPWeak(self, __weakSelf); /** defines a strong `self` named `_self` from `__weakSelf` */ #define TPStrongSelf TPStrong(__weakSelf, _self); ``` 这是对弱引用(weak)和强引用(strong)配合使用的封装,常见于 Objective-C 中避免 **block 内部的循环引用(retain cycle)** 的场景。 --- ### 一、宏定义背后的实现逻辑 这两个宏依赖于另一个宏 `TPWeak` 和 `TPStrong`,它们可能是这样定义的: ```objective-c #define TPWeak(object, weakObject) __weak __typeof__(object) weakObject = object; #define TPStrong(object, strongObject) __strong __typeof__(object) strongObject = object; ``` #### 1. `TPWeakSelf`:定义弱引用的 `__weakSelf` ```objective-c TPWeakSelf ``` 等价于: ```objective-c __weak __typeof__(self) __weakSelf = self; ``` - 创建了一个弱引用的 `self`,命名为 `__weakSelf`。 - 避免 block 强引用 `self`,防止循环引用。 #### 2. `TPStrongSelf`:定义强引用的 `_self` ```objective-c TPStrongSelf ``` 等价于: ```objective-c __strong __typeof__(__weakSelf) _self = __weakSelf; ``` - 从弱引用 `__weakSelf` 提升为强引用 `_self`。 - 确保在 block 执行期间,`self` 不会被释放。 --- ### 二、为什么这样设计? #### 1. 避免循环引用 如果 block 内直接使用 `self`,而 block 又被 `self` 持有(如作为属性),就会形成循环引用: ``` self ──强引用─→ block ──强引用─→ self ``` 使用 `__weakSelf` 可以打破这个循环。 #### 2. 确保 block 执行期间 `self` 不被释放 虽然使用 `__weakSelf` 是安全的,但如果在 block 执行过程中 `self` 被释放,会导致 `__weakSelf` 变为 `nil`,从而中断逻辑。 使用 `TPStrongSelf` 把 `__weakSelf` 转为强引用,确保在 block 执行期间 `self` 不会被释放。 --- ### 三、使用示例 ```objective-c TPWeakSelf someBlock = ^{ TPStrongSelf if (!_self) return; // 安全地使用 _self _self.someProperty = newValue; [_self doSomething]; }; ``` #### 流程说明: 1. `TPWeakSelf` 创建 `__weakSelf`。 2. 在 block使用 `TPStrongSelf` 获取 `_self` 的强引用。 3. 判断 `_self` 是否为 `nil`,防止对象已经被释放。 4. 安全执行操作。 --- ### 四、命名建议 - `__weakSelf`:前缀双下划线,表示内部变量。 - `_self`:命名简洁,符合 block 内部使用习惯。 --- ### 五、优点总结 | 优点 | 说明 | |------|------| | ✅ 安全 | 避免循环引用,防止内存泄漏 | | ✅ 易读 | 宏封装统一命名,便于理解 | | ✅ 易维护 | 可统一替换宏定义,适应不同项目规范 | | ✅ 灵活 | 支持任意对象的弱强引用转换 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值