`

复杂数据类型变量的引用计数与block以及__block修饰符的关系

 
阅读更多

 

以下结论是结合参考资料和实验得来,不对地方请大家纠正:

 

注意不要用NSString做实验,NSString的retainCount一直为-1;

 

1)局部变量(无__block修饰):

只有当block被copy时,局部变量的retainCount加1,同时self的retainCount也加1;

如果block没有被copy那么局部变量的retainCount不变;Block_release时不会把局部和self的retainCount减1的(test1方法);

 

输出:

2012-11-26 12:02:55.822 BlockTest[1843:11303] ======无__block修饰的局部变量

2012-11-26 12:02:55.823 BlockTest[1843:11303] Initial _lo1 retain count is 1

2012-11-26 12:02:55.824 BlockTest[1843:11303] Initial self retain count is 3

2012-11-26 12:02:55.824 BlockTest[1843:11303] _lo1 retain count is 2

2012-11-26 12:02:55.825 BlockTest[1843:11303] self retain count is 4

2012-11-26 12:02:55.825 BlockTest[1843:11303] _lo1 retain count is 1

2012-11-26 12:02:55.826 BlockTest[1843:11303] self retain count is 3

 

2)局部变量(有__block修饰):局部变量的引用数不会受block的影响, self的retainCount受Block_copy影响加1(test2方法)

 

输出:

2012-11-26 12:02:55.826 BlockTest[1843:11303] ======有__block修饰的局部变量

2012-11-26 12:02:55.826 BlockTest[1843:11303] Initial _blo1 retain count is 1

2012-11-26 12:02:55.827 BlockTest[1843:11303] Initial self retain count is 3

2012-11-26 12:02:55.827 BlockTest[1843:11303] _blo1 retain count is 1

2012-11-26 12:02:55.828 BlockTest[1843:11303] self retain count is 4

2012-11-26 12:02:55.828 BlockTest[1843:11303] _blo1 retain count is 1

2012-11-26 12:02:55.828 BlockTest[1843:11303] self retain count is 3

 

3)成员变量(无__block修饰):成员变量的retainCount不受影响,self的retainCount受Block_copy影响加1(test3方法)

 

输出:

2012-11-26 12:02:55.829 BlockTest[1843:11303] ======无__block修饰的成员变量

2012-11-26 12:02:55.829 BlockTest[1843:11303] Initial _instanceV retain count is 1

2012-11-26 12:02:55.830 BlockTest[1843:11303] Initial self retain count is 3

2012-11-26 12:02:55.830 BlockTest[1843:11303] _instanceV retain count is 1

2012-11-26 12:02:55.831 BlockTest[1843:11303] self retain count is 4

2012-11-26 12:02:55.831 BlockTest[1843:11303] _instanceV retain count is 1

2012-11-26 12:02:55.831 BlockTest[1843:11303] self retain count is 3

 

4)成员变量(有__block修饰):结论同3)(test4方法)

 

输出:

2012-11-26 12:02:55.832 BlockTest[1843:11303] ======有__block修饰的成员变量

2012-11-26 12:02:55.832 BlockTest[1843:11303] Initial _instanceV2 retain count is 1

2012-11-26 12:02:55.833 BlockTest[1843:11303] Initial self retain count is 3

2012-11-26 12:02:55.833 BlockTest[1843:11303] _instanceV2 retain count is 1

2012-11-26 12:02:55.833 BlockTest[1843:11303] self retain count is 4

2012-11-26 12:02:55.847 BlockTest[1843:11303] _instanceV2 retain count is 1

2012-11-26 12:02:55.847 BlockTest[1843:11303] self retain count is 3

 

5)block中不引用任何外部变量:没有Block_copy这行代码self的retainCount是不会加1的

 

输出:

2012-11-26 12:07:51.966 BlockTest[1881:11303] ======block中不引用任何外部变量

2012-11-26 12:07:51.967 BlockTest[1881:11303] Initial self retain count is 3

2012-11-26 12:07:51.967 BlockTest[1881:11303] self retain count is 4

2012-11-26 12:07:51.967 BlockTest[1881:11303] self retain count is 4

2012-11-26 12:07:51.968 BlockTest[1881:11303] self retain count is 3

 

综上:

1)无__block修饰的局部变量只有在Block_copy时retainCount才会加1;

2)有__block修饰的局部变量和成员变量的retainCount不受Block_copy的影响;

3)Block_release不会把引用的外部变量和self的retainCount减1;

4)Block_copy会把self的retainCount加1,无论block内部有没有引用局部和成员变量;

所以Block_copy慎用!Block_release时不要忘了把局部变量和self也release一次;

0
0
分享到:
评论

相关推荐

    block回调 基础的看看

    如果Block内部持有强引用的对象,可能导致循环引用,这时可以使用`__weak`修饰符弱化引用,或者使用`__block`修饰符让Block内可以修改该变量的引用计数。 ### 5. Block的返回值与参数 Block不仅可以没有返回值,也...

    cpp-block的实现原理

    此外,当Block捕获变量时,如果变量是强引用类型,Block会自动增加其引用计数,以避免过早释放。 Block的调用就像调用普通函数一样,但Block的类型系统更加复杂。Block类型由参数列表和返回类型决定,例如`void (^)...

    block的简单使用

    为避免这种情况,可以使用`__weak`或`__block`修饰符来弱引用或修改捕获的对象。 三、Block的类型与内存管理 Block有三种类型:栈Block、堆Block和全局Block,它们的生命周期和内存管理策略不同。栈Block生命周期...

    iOS block使用总结

    为了避免这种情况,可以使用`__weak`修饰符来弱引用self,或者使用`__unsafe_unretained`。 8. **Block与 ARC** 自动引用计数(ARC)管理Block的内存,但需要开发者理解Block是如何捕获和存储变量的,以避免内存...

    《Ios组件与框架-iOS SDK 高级特性刨析》代码 全部之ARC部分

    在ARC中,可以使用`__strong`、`__weak`、`__unsafe_unretained`和`__autoreleasing`这四种修饰符来指定变量的引用计数行为。其中,`__unsafe_unretained`与`__strong`类似,但不处理对象的释放,可能导致野指针问题...

    ARC到底帮我们做了哪些工作?(v1.3)

    - **__block修饰符**:用于在Block内部修改对象,它使Block持有弱引用,避免了引用计数增加。 ### 5. `@autoreleasepool` `@autoreleasepool`是ARC中实现自动释放池的关键。在一次事件循环中,所有在池中的对象在...

    Smarty中文手册 chm版

    $default_resource_type [默认源类型变量] 13. Methods [方法] append [添加] append_by_ref [引用添加] assign [赋值] assign_by_ref [引用赋值] clear_all_assign [清除所有赋值] clear_all_cache [清除...

    smarty手册.chm

    $default_resource_type [默认源类型变量] 13. Methods [方法] append [添加] append_by_ref [引用添加] assign [赋值] assign_by_ref [引用赋值] clear_all_assign [清除所有赋值] clear_all_cache [清除...

    objective-C的核心内容.doc

    Objective-C的GCD提供了高效的多线程解决方案,而其内存管理机制则需要开发者理解所有权修饰符的概念以及如何正确使用各种方法来避免内存泄漏和野指针等问题。掌握这些核心概念对于编写高效、稳定的Objective-C应用...

    iOS内存管理方面的面试题汇总

    3. `assign`:不改变对象的引用计数,适用于基本数据类型,可能会导致KVO失效。 4. `weak`:不持有对象,对象释放后,弱引用自动设为`nil`,避免循环引用,适用于代理、观察者等场景。 5. `_unsafe_unretain`:类似...

    招聘一个靠谱ios面试题答案(下)

    14. 在block内部修改外部变量,需要使用__block修饰符来声明该变量,以便在block内部修改其值。 15. 使用系统的blockAPI时,也需要考虑引用循环的问题,因为这些API实现中可能隐式地捕获了外部变量。 16. GCD的...

    30道iOS底层面试题

    4. **Block**:理解Block的工作原理,包括内存管理(__strong, __weak, __block修饰符)、捕获变量、循环引用问题,以及Block与多线程的关系。 5. **自动布局**:Auto Layout的约束计算和视图更新机制,以及如何...

    iOS笔试题

    综上所述,本篇解析涵盖了 Objective-C 中重要的概念,包括但不限于 `#import` 与 `#include` 的区别、属性修饰符的作用、内存管理机制以及线程的创建与调度等。这些知识点对于理解 iOS 开发的基础至关重要。

    iOS 5 ARC完全指南

    ARC对Objective-C中的属性类型有特殊处理,支持`strong`和`weak`两种属性修饰符。`strong`属性会自动保留对象的引用,而`weak`属性则不会保留引用,这有助于避免循环引用的问题。例如: ```objective-c @property ...

    objc代码-Objc - 循环引用1

    - 使用__block修饰符:在Block中,可以使用__block修饰变量,让其在Block内可以被重新赋值,从而避免循环引用。 4. ARC(Automatic Reference Counting)与循环引用: 自动引用计数(ARC)是Objective-C的内存...

    iOS笔试题041

    - **assign**:用于非Objective-C对象,如基本数据类型,或防止循环引用的情况。 - **retain**:用于Objective-C对象,增加对象的引用计数。 9. **对象的释放**: - 对象的引用计数变为0时会被释放。`release`或...

    史上最全的iOS面试题及答案 - 张明炜 - ITeye技术网站1

    - `strong`、`weak`、`retain`、`assign`、`copy` 和 `nonatomic` 是Objective-C中的属性修饰符。`strong`(或`retain`在非ARC环境下)用于保持对象的引用计数,`weak`用于弱引用,防止循环引用,`assign`适用于非...

    iOS面试 面试必备神器

    1. **`assign`**:用于基本数据类型的简单赋值,适用于数值类型和指针。 2. **`retain`**:增加对象的引用计数,表明当前对象获得了对所指对象的所有权。 3. **`copy`**:用于复制对象,常见于字符串等不可变对象。 ...

Global site tag (gtag.js) - Google Analytics