今日帮着同事把老项目从MRC迁移至ARC,大部分工作无非是删除release,[super dealloc]等方法,只要关闭了MRC编译选项后,编译器能自动帮你检查,block就有一些不一样了,发现许多做iOS开发的同学,对于指针的原理及操作并不明确。下面的如果有错误,也欢迎指正。

__blcok

__block关键字在MRC和ARC下并不一样

MRC:用__block修饰的对象在block中不被retain,就像ARC中的__weak类似。

ARC:用__block修饰的变量在被block捕获时,获取的是该变量的指针,这才能保证该变量可以被block所更改。

在ARC下举个例子

    __block long a = 5;
void (^blockObject)(void) = ^{ a = 6;};
blockObject();

这里我们改变基本类型变量a的值,如果不是用__block的话,也是可以做到的.熟悉c语言的同学都应该知道,传递指针

    long b = 5;
long *bPointer = &b;
void (^blockObjectNo__block)(void) = ^{ *bPointer = 6;};
blockObjectNo__block();

其实OC中__block的也基本上就是这么实现的,只不过为了方便开发者入门,将这个过程转化为关键字,形势上看起来就像是直接赋值给了变量,本质仍然是传递的是指针。

指针的指针

如果在block中你需要给指针赋值,那么仍然需要__block。可能你会困惑,不是只有基本类型才需要__blcok么,在这里不是本来就是指针么?

正确示例
__block NSObject *originO = [[NSObject alloc] init];
void (^blockO)(void) = ^{ originO = [[NSObject alloc] init];};
blockO();
错误示例
NSObject *originO = [[NSObject alloc] init];
void (^blockO)(void) = ^{ originO = [[NSObject alloc] init];};
blockO();

思路和上面的基本类型一致.block中捕获的仍然是个拷贝指针。可以见下图,图中捕获的originO1这个指针是原来的拷贝,指向同一个堆上的对象。



当进行赋值之后,见下图,更改的不是原来的指针,而是拷贝的指针,指向了block内alloc出来的对象。这就是为什么要写__block的原因。



当然你可以像上面一样,建立指针的指针。

    NSObject *originO1 = [[NSObject alloc] init];
NSObject *__strong *pOriginO = &originO1;
void (^blockO_No__block)(void) = ^{ *pOriginO = [[NSObject alloc] init];};
blockO_No__block();

这样也是可以做到的,有的同学可能会比较蒙。其实就是创建了一个指针,这个指针指向一个NSObject *类型的指针。这样拷贝的是指针的指针,就可以获取到原来的指针,就可以修改了。

MRC迁移ARC之__block的更多相关文章

  1. iOS-旧项目中手动内存管理(MRC)转ARC

    在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题, ...

  2. MRC转ARC(2)

    春节前抽空花了一天的时间将手头的工程从MRC转成了ARC,然后陆陆续续地修复一部分因为转ARC引起的内存泄漏和崩溃,到目前为止工程也算是比较稳定了,抽空记上一笔.(虽说这种事情这辈子估计都只会做这么一 ...

  3. Objective-c的内存管理MRC与ARC

    Objective-c的内存管理MRC与ARC   Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Referen ...

  4. 内存管理-MRC与ARC详解

    Objective-C提供了两种内存管理机制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),为Objective-C提 ...

  5. MRC转ARC

    转载请注明出处:http://blog.csdn.net/cywn_d/article/details/18222671 1.删除所有retain,release和autorelease. 2.把原来 ...

  6. 【Bugly干货分享】iOS内存管理:从MRC到ARC实践

    Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...

  7. MRC BlOCK ARC

       /*-------------------MRC环境中-------------------------*/     //使用局部变量:a到block块中,为了在block中能够使用这个变量,将 ...

  8. @autoreleasepool在MRC和ARC中的区别

    对于@autoreleasepool {} (1)在ARC中会销毁所有在里面创建的对象,即使你用外面的Strong指针指向他 (2)在MRC中如果有外部的强指针指向,不会销毁对象,retainCoun ...

  9. MRC和ARC混编

    iOS5.0以后就开始可以使用ARC( Automatic Reference Counting:自动引用计数)来代替之前的MRC(Manual Reference Counting:人工引用计数). ...

随机推荐

  1. 用 JSP 实现对文件的相关操作

    前段时间一直忙着作业,实验,动手的时间真是少之又少,今天终于可以继续和大家分享关于 JSP 的学习心得. 简单总结一下吧: JSP 理论性很强,感觉就是纯语法. 我更偏向于实际编写代码,这样更容易理解 ...

  2. ANSI Common Lisp Practice - My Answers - Chatper - 3

    Ok, Go ahead. 1 (a) (b) (c) (d) 2 注:union 在 Common Lisp 中的作用就是求两个集合的并集.但是这有一个前提,即给的两个列表已经满足集合的属性了.具体 ...

  3. ZOJ People Counting

    第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ  3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...

  4. [No000095].Net入门级逆向工程-1.SpreadsheetGear汉化

    一.SpreadsheetGear汉化 最近,我们的有个项目要用到表格功能,由于历(la)史(ji)遗(kuang)留(jia)的问题,我们不得不用第三方的一个插件SpreadsheetGear来实现 ...

  5. /var/log/messages

    messages 该日志文件是许多进程日志文件的汇总,从该文件可以看出任何入侵企图或成功的入侵,包括整体系统信息,是系统最核心的日志.它包含了系统启动时的引导消息,以及系统运行时的其他状态消息.IO ...

  6. BZOJ1878[SDOI2009]HH的项链

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变 ...

  7. 用于科学计算的Python库

    Matplotlib NumPy Pandas SciPy SymPy

  8. Ajax入门(二)

    接收服务器返回的消息 1,定义触发Ajax的js效果 2,创建Ajax方法 如果返回的数据是XML,则需使用aj.responseXML 3,接收服务器返回的消息,并显示在网页上 错误案例:直接接收服 ...

  9. StringHelper

    /// <summary> /// 文本取左边 /// </summary> /// <param name="str"></param& ...

  10. ubuntu下面更改用户名的方法

    在装HADOOP 系统时候不小心, 没有将三台机器的用户名设置为一致的用户名,导致后面发生很多麻烦.下面总结一下UBUNTU中改用户名的方法. 1.  先给系统添加一个super用户,我们用这个用户名 ...