我搜索了许多链接并阅读了很多文章,但我找不到retain
和assign
的确切差异..
我正在尝试以下方法:
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
)
上面的示例给出了相同的输出。
考虑到上面的示例,我如何定义assign
和retain
之间的差异?
如果以上示例有误,请提供更好的示例提供答案。
答案 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
减少为零,因此当自动释放池耗尽时,对象将被释放...无法减少计数器正确的地方可能导致物品泄露。
您可以想象,这会导致一个相当脆弱的过程,我们必须确保通过右侧的retain
,release
和autorelease
增加和减少保留计数地方。 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
)还是间接引用并不重要。