首先要说说什么时候使用weakSelf和strongSelf。

下面引用一篇博客《到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf》的内容:

Objective C 的 Block 是一个很实用的语法,特别是与GCD结合使用,可以很方便地实现并发、异步任务。但是,如果使用不当,Block 也会引起一些循环引用问题(retain cycle)—— Block 会 retain ‘self’,而 ‘self‘ 又 retain 了 Block。因为在 ObjC 中,直接调用一个实例变量,会被编译器处理成 ‘self->theVar’,’self’ 是一个 strong 类型的变量,引用计数会加 1,于是,self retains queue, queue retains block,block retains self。

解决 retain circle

Apple 官方的建议是,传进 Block 之前,把 ‘self’ 转换成 weak automatic 的变量,这样在 Block 中就不会出现对 self 的强引用。如果在 Block 执行完成之前,self 被释放了,weakSelf 也会变为 nil。

示例代码:

1 __weak __typeof__(self) weakSelf = self;
2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3 [weakSelf doSomething];
4 });

clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:

1 __weak __typeof__(self) weakSelf = self;
2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3 [weakSelf doSomething];
4 [weakSelf doOtherThing];
5 });

在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,于是,strongSelf 就派上用场了:

1 __weak __typeof__(self) weakSelf = self;
2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3 __strong __typeof(self) strongSelf = weakSelf;
4 [strongSelf doSomething];
5 [strongSelf doOtherThing];
6 });

__strong 确保在 Block 内,strongSelf 不会被释放。

总结

  • 在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。
  • 如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。

-------------------------------分割线---------------------------------------------

以上内容知道了我们为什么要用weakSelf和strongSelf, 为了简单实用一般会定义成宏weakify和strongify,如下:

 1 #ifndef    weakify
2 #if __has_feature(objc_arc)
3
4 #define weakify( x ) \
5 _Pragma("clang diagnostic push") \
6 _Pragma("clang diagnostic ignored \"-Wshadow\"") \
7 autoreleasepool{} __weak __typeof__(x) __weak_##x##__ = x; \
8 _Pragma("clang diagnostic pop")
9
10 #else
11
12 #define weakify( x ) \
13 _Pragma("clang diagnostic push") \
14 _Pragma("clang diagnostic ignored \"-Wshadow\"") \
15 autoreleasepool{} __block __typeof__(x) __block_##x##__ = x; \
16 _Pragma("clang diagnostic pop")
17
18 #endif
19 #endif
20
21 #ifndef strongify
22 #if __has_feature(objc_arc)
23
24 #define strongify( x ) \
25 _Pragma("clang diagnostic push") \
26 _Pragma("clang diagnostic ignored \"-Wshadow\"") \
27 try{} @finally{} __typeof__(x) x = __weak_##x##__; \
28 _Pragma("clang diagnostic pop")
29
30 #else
31
32 #define strongify( x ) \
33 _Pragma("clang diagnostic push") \
34 _Pragma("clang diagnostic ignored \"-Wshadow\"") \
35 try{} @finally{} __typeof__(x) x = __block_##x##__; \
36 _Pragma("clang diagnostic pop")
37
38 #endif
39 #endif

使用过RAC的同学应该都知道@weakify和@strongify,这两个宏在RAC中是已经定义好的,可以直接用,属于比较牛逼的写法。这两个宏一定成对出现,先@weakify再@strongify.可以很好的管理Block内部对self的引用。可以一步步点开发现其实使用到了C语言中的组合运算符。

1 @weakify(self);
2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
3 @strongify(self);
4 [self doSomething];
5 [self doOtherThing];
6 });

@weakify, @strongify ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify的更多相关文章

  1. ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify

    首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...

  2. 到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf

    转载,原文: http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block ...

  3. iOS Block中的weakSelf/strongSelf

    Objective C 的 Block 是一个很实用的语法,特别是与GCD结合使用,可以很方便地实现并发.异步任务.但是,如果使用不当,Block 也会引起一些循环引用问题(retain cycle) ...

  4. 【转载】在block中使用weakSelf/strongSelf

    http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block/

  5. iOS 面试题(二):什么时候在 block 中不需要使用 weakSelf --转自唐巧

    问题 我们知道,在使用 block 的时候,为了避免产生循环引用,通常需要使用 weakSelf 与 strongSelf,写下面这样的代码: __weak typeof(self) weakSelf ...

  6. 关于 Block 中捕获 self 的分析

    问题 最近遇到一个已经使用了weak-strong dance的block依旧强引用了self的情况,好在block没被VC持有只是延迟释放,但这里的关键是用了weak_self的blcok理应不会强 ...

  7. Block中的引用循环

    原文地址:http://www.cnblogs.com/lujianwenance/p/5910490.html Block在实际的开发中非常的常用,事件回调.传值.封装成代码块调用等等.很多人都对b ...

  8. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(下)- block中任性用self

    前言: 在处理完框架内存泄漏的问题后,见上篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug 发现业务代码有一个地方的内存没释放,原因很也简单: ...

  9. iOS开发-多层嵌套block中如何使用__weak和__strong

    1.关于__weak__weak只能在ARC模式下使用,也只能修饰对象(比如NSString等),不能修饰基本数据类型(比如int等)__weak修饰的对象在block中不可以被重新赋值.__weak ...

随机推荐

  1. next()与nextLine的区别

    next():    1.一定要读取到有效字符后才可以结束输入.    2.对输入有效字符之前遇到的空白,next() 方法会自动将其去掉.    3.只有输入有效字符后才将其后面输入的空白作为分隔符 ...

  2. Daily Scrum 10.30

    由于最近一段时间吴文会同学身体欠安,经过讨论我们对任务做了一下调整,暂时由罗洪运同学接手界面部分的开发.部分进度较快的同学的任务已经快要完成,工作重点也会转为整体开发和协助其他同学开发. 下面是今天的 ...

  3. javascript平时小例子③(setInterval使用1)

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  4. 20145337《JAVA程序设计》第七周学习总结

    20145337 <Java程序设计>第七周学习总结 教材学习内容总结 时间的度量 格林威治时间GMT,世界时UT,国际原子时TAI,世界协调时间UTC 就目前来说,即使标注为GMT,实际 ...

  5. python的内存管理机制

    先从较浅的层面来说,Python的内存管理机制可以从三个方面来讲 (1)垃圾回收 (2)引用计数 (3)内存池机制 一.垃圾回收: python不像C++,Java等语言一样,他们可以不用事先声明变量 ...

  6. IOS第一天多线程-04GCD通信

    **** #define HMGlobalQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) #define HMM ...

  7. ul+li标签制作表格

    table标签制作表格代码繁琐,且不方便后期代码维护. li标签加上css的浮动样式可以制作多种样式的表格. 代码如下: <ul id="ttttt" style=" ...

  8. php Output Control 函数 ob_系列函数详解

    <?php /* * 输出缓冲控制 * * flush — 刷新输出缓冲 ob_clean — 清空(擦掉)输出缓冲区 ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲 ob_en ...

  9. SVN 分支管理

    平时在工作中使用 SVN 只是限于 commit,update 这样的操作,至多再 reslove 解决一下冲突,没有用过分支管理.开发过程中一般都是一个功能开发完成之后整体进行提交,而最近在项目中有 ...

  10. 我自己的Javascript 库,封装了一些常用函数 Kingwell.js

    我自己的Javascript 库,封装了一些常用函数 Kingwell.js 博客分类: Javascript javascript 库javascript库  现在Javascript库海量,流行的 ...