保留和分配有什么区别

时间:2016-08-15 12:13:35

标签: ios objective-c memory-management automatic-ref-counting reference-counting

我搜索了许多链接并阅读了很多文章,但我找不到retainassign的确切差异..

我正在尝试以下方法:

NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:@"1",@"2",@"3", nil];
NSMutableArray *arr2=[arr1 retain];
NSMutableArray *arr3 = arr1; //Assign

[arr1 addObject:@"66"];

NSLog(@"Array one   : %@",arr1);
NSLog(@"Array two   : %@",arr2);
NSLog(@"Array three : %@",arr3);

输出:

Array one   : (
    1,
    2,
    3,
    66 
)  

Array two   : (
        1,
        2,
        3,
        66
)  

Array three : (
        1,
        2,
        3,
        66 
)

上面的示例给出了相同的输出。

考虑到上面的示例,我如何定义assignretain之间的差异?

如果以上示例有误,请提供更好的示例提供答案。

2 个答案:

答案 0 :(得分:5)

您正在查看指向同一对象的三个不同变量,因此当您显示输出时,您每次都会看到相同的对象。

retain vs assign是内存限定符的类型,但不会影响底层对象的内容。具体来说,它们只会影响基础对象的retainCount

让我们看看你的三行代码:

NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:@"1",@"2",@"3", nil];

这会创建一个保留计数为+1的对象。

NSMutableArray *arr2 = [arr1 retain];

这会将该对象的保留计数增加到+2,并且您有另一个指向同一对象的变量。

NSMutableArray *arr3 = arr1; //Assign

这不会进一步增加保留计数,现在您有第三个指向同一对象的变量。

"引用计数的基本游戏"内存管理是为了确保:

  • 正在使用的对象具有正保留计数(因此在您仍在使用它时它不会被释放)...未能正确执行此操作会导致对象过早解除分配,可能会留下你悬挂的参考资料;以及

  • 一个没有进一步使用的对象,其retainCount减少为零,因此当自动释放池耗尽时,对象将被释放...无法减少计数器正确的地方可能导致物品泄露。

您可以想象,这会导致一个相当脆弱的过程,我们必须确保通过右侧的retainreleaseautorelease增加和减少保留计数地方。 Xcode"静态分析仪" ("分析器"选项在Xcode' s"产品"菜单或按 shift + 命令 + B )能够很好地查看我们的代码并确定我们是否已正确完成此操作。如果您正在编写手动引用计数代码,则此工具是必不可少的。

但是," automatic reference counting"的美丽是我们离开这个愚蠢的世界,增加和减少我们身后的对象retainCount值。我们转向一个我们可以专注于" object graph"的世界,我们在代码中的某些位置需要什么样的引用,编译器负责递增和递减{{ 1}}对我们来说。

答案 1 :(得分:3)

所有3个引用都指向同一个实例。

NSMutableArray *arr2=[arr1 retain];
增加引用计数并返回指向同一实例的指针(即self)。

NSMutableArray *arr3 = arr1;
直接指定arr1引用,而不通过任何方法调用。

唯一的区别是你在一个案例中增加了引用次数,而在另一个案例中你没有增加引用次数。
分配参考的机制是相同的。通过调用返回对自身的引用的arr3 = arr1上的方法,引用是直接(arr1)还是间接引用并不重要。