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

2019-02-15  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读