今日帮着同事把老项目从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. everything + autohotkey的配合使用

    一,everything是文件搜索神奇,瞬间定位到文件,在众多的文件中找到你需要的文件.(百度下载就好,分32位和64位)   二,autohotkey是热键启动设置,方便的打开常用的应用. 直接使用 ...

  2. 继承AppCompatActivity的Activity隐藏标题栏

    继承了AppCompatActivity的Activity无法通过调用requestWindowFeature(Window.FEATURE_NO_TITLE)来隐藏标题栏. public class ...

  3. 使用 iscroll 实现焦点图无限循环

    现在大家应该都看到过焦点图轮播的效果,这个效果是什么样我就不截图了.昨天做练习,练习要求是使用iscroll实现焦点图的无限循环滚动,并且当手指触摸焦点图后,停止焦点图的循环滚动.第一次接触iscro ...

  4. [LeetCode] Max Points on a Line 共线点个数

    Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...

  5. 分分钟带你玩转 Web Services

    当大型需求被数个公司分割开来,各公司系统相互交换数据的问题就会接踵而来. 毕竟是多家不同的公司的产品,研发开发语言.采用技术框架基本上是百花齐放. 怎样让自家系统提供的服务具有跨平台.跨语言.跨各种防 ...

  6. Linux常用获取进程占用资源情况手段

    测试环境:Ubuntu14.04 1.  获取进程ID号 ps -aux | grep your_process_name 例如: xxx@xxx:~$ ps -e |grep Midlet|awk ...

  7. nginx 虚拟主机配置

    user nginx; #代表使用的用户 worker_processes auto; #工作衍生进程数,一般代表系统cpu核数一到两倍最好 error_log /var/log/nginx/erro ...

  8. tkinter事件机制

    一.tkinter.Event tkinter的事件机制跟js是一样的,也是只有一个Event类,这个类包罗万象,集成了键盘事件,鼠标事件,包含各种参数. 不像java swing那种强类型事件,sw ...

  9. iOS中富文本NSMutableAttributedString的用法

    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc]initWithString:@"我是富文 ...

  10. nginx代理TCP端口

    1.升级nginx 版本至1.9.0以上 升级流程参考 nginx平滑升级 2.配置编译的时候需要加上 ./configure --prefix=/usr/local/nginx --user=www ...