美文网首页
MRC返回值所有权关系列举与描述

MRC返回值所有权关系列举与描述

作者: 传说中的汽水枪 | 来源:发表于2019-02-15 15:11 被阅读4次

    作者:传说中的汽水枪
    地址:https://www.jianshu.com/p/bd504fcb5b15
    版权所有,欢迎转载,转载请注明出处,欢迎留言评论。

    RXARCTmpObject

    @implementation RXARCTmpObject
    - (NSString *)description
    {
        return NSStringFromClass([self class]);
    }
    - (void)dealloc
    {
        NSLog(@"RXARCTmpObject dealloc");
    }
    @end
    

    从被调用者(callee)转移到自动释放池(autorelease)

    - (id)_foo_ownership_from_callee_to_autorelease
    {
        RXARCTmpObject *object = [[RXARCTmpObject alloc] init];
        NSLog(@"count after alloc init:%zd", [object retainCount]);
        return [object autorelease];
    }
    - (void)_test_ownership_from_callee_to_autorelease
    {
        id object = [self _foo_ownership_from_callee_to_autorelease];
        NSLog(@"count after call method:%zd", [object retainCount]);
        NSLog(@"%@", object);
    }
    

    输出:

    count after alloc init:1
    count after call method:1
    RXARCTmpObject
    RXARCTmpObject dealloc
    

    从被调用者(callee)到调用者(caller)(方法一)

    - (id)_foo_ownership_from_callee_to_caller
    {
        RXARCTmpObject *object = [[RXARCTmpObject alloc] init];
        NSLog(@"count after alloc init:%zd", [object retainCount]);
        return object;
    }
    - (void)_test_ownership_from_callee_to_caller
    {
        id object = [self _foo_ownership_from_callee_to_caller];
        NSLog(@"count after call method:%zd", [object retainCount]);
        NSLog(@"%@", object);
        NSLog(@"before release");
        [object release]; // 如果没有这一行,object会内存泄漏
        NSLog(@"after release");
    }
    

    输出:

    count after alloc init:1
    count after call method:1
    RXARCTmpObject
    before release
    RXARCTmpObject dealloc
    after release
    

    从被调用者(callee)到调用者(caller)(方法二)

    - (id)_foo_ownership_from_callee_to_caller_2
    {
        RXARCTmpObject *object = [[RXARCTmpObject alloc] init];
        NSLog(@"count after alloc init:%zd", [object retainCount]);
        id returnValue = [object retain]; // 因为需要返回,所以先retain一次
        [object release]; // 谁申请谁释放原则,有一个alloc init,就有一个release
        return returnValue;
    }
    - (void)_test_ownership_from_callee_to_caller_2
    {
        id object = [self _foo_ownership_from_callee_to_caller_2];
        NSLog(@"count after call method:%zd", [object retainCount]);
        NSLog(@"%@", object);
        NSLog(@"before release");
        [object release]; // 如果没有这一行,object会内存泄漏
        NSLog(@"after release");
    }
    

    输出:

    count after alloc init:1
    count after call method:1
    RXARCTmpObject
    before release
    RXARCTmpObject dealloc
    after release
    

    中间总结:

    方法一和方法二结果是一样的,只不过写法不一样。注意到函数产生的返回值都是通过alloc方式产生的。

    通过其他方式产生的对象(非alloc,copy,mutableCopy,new)作为返回值

    - (id)_foo_ownership_noChange
    {
        
        RXARCTmpObject *object = [[RXARCTmpObject alloc] init];
        NSString *str = [NSString stringWithFormat:@"%@", object]; // 这个内存是由 stringWithFormat 方法管理的
        [object release];
        NSLog(@"count after product:%zd", [str retainCount]);
        return str;
    }
    - (void)_test_ownership_noChange
    {
        NSString *str = [self _foo_ownership_noChange];
        NSLog(@"count after call method:%zd", [str retainCount]);
        NSLog(@"str:%@", str);
    }
    

    输出:

    RXARCTmpObject dealloc
    count after product:1
    count after call method:1
    str:RXARCTmpObject
    

    相关文章

      网友评论

          本文标题:MRC返回值所有权关系列举与描述

          本文链接:https://www.haomeiwen.com/subject/cgspeqtx.html