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