【iOS】MRC_AND_ARC

项目设置


  1. 设置项目为ARC或者为MRC
    在TARGETS -> Build Setting -> Apple LLVM 8.0 - Language - Objective C -> Objective-C Automatic Reference Counting 设置其为YES(ARC)或者NO(MRC)

  2. ARC和MRC混编
    在TARGETS -> Build Phases -> Compile Sources中选择对应文件设置其Compiler Flags

  • ARC项目按照MRC编译 -fno-objc-arc
  • MRC项目按照ARC编译 -fobjc-arc

MRC


  1. MRC文件一定要有dealloc 并且一定要有[super dealloc] 而且放到最后面

  2. 系统自带的方法里面没有包含alloc,new ,copy说明返回的对象都是autorelease的

  3. autoreleasepool是一种结构,不再是OC对象作用域与普通{ }一样。

  4. 先release后设置为nil 。绝对不可以先nil,在release。

  5. 多对象内存管理原则

    • 你想使用(占用)某个对象,就应该让对象的计数器+1 (让对象做一次retain操作)
  • 你不想再使用(占用)某个对象,就应该让对象的计数器-1 (让对象做一次release操作)
  • 谁retain,谁release
  • 谁alloc,谁release
  1. 代码规范
  • Foundation对象(OC对象) : 只要方法中包含了alloc \ new \ copy \ mutableCopy \ retain等关键字, 那么这些方法产生的对象, 就必须在不再使用的时候调用1次release或者1次autorelease
  • CoreFoundation对象(C对象) : 只要函数中包含了create \ new \ copy \ retain等关键字, 那么这些方法产生的对象, 就必须在不再使用的时候调用1次CFRelease或者其他release函数
  1. 在MRC Block使用WeakSelf防止循环引用,但是此时有延时操作的话 可以用 malloc_zone_from_ptr(weakObj) 判断weakSelf是否存在

ARC


  1. 使用Core Foundationmalloc(size_t __size)开辟空间之后,你仍然对其内存管理负有责任需要在适当时候使用free(void *)以释放内存防止泄露
    void *p = malloc(3);
    free(p);//需要free()
  1. 因为ARC只对 objective-c 有效,而Core 开头的底层C语言库是没有使用编译器的特性ARC的,需要开发者手动进行内存管理(只要函数中包含了create \ new \ copy \ retain等关键字, 那么这些方法产生的对象, 就必须在不再使用的时候调用1次CFRelease或者其他release函数);并且在ARC中Core 开头的底层C语言库和OC中的库互相转换的时候需要使用(__bridge type)进行桥接,以Core Foundation为例进行说明。

    • 如果要使用Core Foundation,需要把数据类型进行转换,添加(__bridge type);但是(__bridge type)不对程序的内存管理做任何事情,不会更换对象的所有权,原来是ARC管理的对象还继续ARC管理,MRC的还继续MRC管理
      注意:(__bridge type)只存在于ARC中,(__bridge type)Core FoundationFoundation转换的桥梁,既可以Foundation -> Core Foundation,同样也能达到Core Foundation -> Foundation的效果
    //Foundation -> Core Foundation
    id a = [[NSObject alloc] init];
    void *p = a;//void *是属于Core Foundation,ARC中会报错“Implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast” void *p = (__bridge void *)(i);
    void *p = (__bridge void *)(a);//正确写法
    //Core Foundation -> Foundation
    void * q = 0;
    id b = (__bridge id)q;
+ `Foundation` **->** `Core Foundation` 解除 ARC 的所有权
    `__bridge_retained`和`CFBridgingRetain`:桥接的基础上对相关数据进行一次retained操作,防止被释放而Crash(EXC_BAD_ACCESS) 。

注意:最后一定要对p进行一次release操作(因为进行了一次retain) 否则内存泄漏

    void *p;
    {
        id obj = [[NSObject alloc] init];
//        p = (__bridge void *)obj;//错误写法 导致EXC_BAD_ACCESS
        p = (__bridge_retained void *)obj;//正确写法 
        //或者使用下面一种写法 效果是一样的 都相当于[p retain] 对p进行一次retain操作
        p = (void*)CFBridgingRetain(obj);//正确写法
    }   
    NSLog(@"class=%@", [(__bridge id)p class]);//如果使用错误写法 这里访问的是僵尸对象
   CFRelease(p);//切记最后一定要进行一次release操作  否则内存泄漏
 +  `Core Foundation` **->** `Foundation` 给予 ARC 所有权
`__bridge_transfer`和`CFBridgingRelease`:桥接的接触上对相关数据进行了一次release操作,就不用再显式地对`Core Foundation` 数据进行`CFRelease(CFTypeRef cf)`操作了
    const char *bytes;
    CFStringRef coreStr;
    bytes = CFAllocatorAllocate(CFAllocatorGetDefault(),6,0);
    strcpy(bytes,"wp");
    coreStr = CFStringCreateWithCStringNoCopy(NULL,bytes,kCFStringEncodingMacRoman,NULL);
    //NSString *str = CFBridgingRelease(coreStr);
    NSString *str = (__bridge_transfer NSString *)coreStr;//不用再release操作了

总结:

  1. Core Foundation 对象类型不在 ARC 管理范畴内,需要自己管理
  2. __bridge只做类型转换,但是不修改对象(内存)管理权,原来是ARC管理的还用ARC,原来MRC管理的继续用MRC
  3. __bridge_retained(也可以使用CFBridgingRetain)将Objective-C的对象转换为Core Foundation的对象,同时将对象(内存)的管理权交给我们,后续需要使用CFRelease或者相关方法来释放对象;
  4. __bridge_transfer(也可以使用CFBridgingRelease)将Core Foundation的对象转换为Objective-C的对象,同时将对象(内存)的管理权交给ARC。

END

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容