这个问题在这里已有答案:
我搜索了许多链接并阅读了很多文章,但我找不到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
之间的区别?
如果以上示例有错,请提供更好的示例提供答案。
您正在查看指向同一对象的三个不同变量,因此当您显示输出时,您每次都会看到相同的对象。
retain
与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的“产品”菜单上的“分析器”选项或按下shift +命令+ B)可以很好地查看我们的代码并确定我们是否已正确完成此操作。如果您正在编写手动引用计数代码,则此工具是必不可少的。
但是,“automatic reference counting”的美妙之处在于,我们离开这个愚蠢的世界,增加和减少我们身后的retainCount
对象的价值。我们转向一个我们可以专注于“object graph”的世界,我们在代码中的某些地方需要什么样的引用,编译器负责为我们增加和减少retainCount
。
assign
和retain
是与Objective-C中的内存管理相关的两种策略。
无论如何,在对象上调用retain不会改变它的值,所以你得到相同的输出是正常的。
retain
/ release
在iOS的早期阶段在Objective-C中引入和推广,当时由于性能问题苹果禁止使用垃圾收集器进行ios开发。由于缺少垃圾收集器,开发人员不得不在不再需要时手动处理对象销毁。因此,相当挑战,retain
/ release
是帮助开发人员更好地处理这个问题的一种方式。
从iOS 5开始,Apple推出了ARC(自动引用计数),它必须用于任何新的开发,特别是如果您不熟悉内存管理。 ARC允许开发人员在编译过程中添加内存管理代码(即[object retain]
和[object release]
)时,使用retain / release停止管理对象生命周期。然后,开发人员在声明属性时只关心内存管理:
@property(assign) int value;
@property(strong) id object;
@property (weak) id object;
在这种情况下,强大和保留是相似的,可以交换。强弱只是新词,让初学者更容易理解幕后发生的事情。此外,assign还假定为par默认值,因此不是必需的。
标记为strong的属性将在setObject期间接收保留调用:将标记为weak的属性不会。由于retain仅适用于对象(在Heap中实例化),因此基本C类型属性(bool,int,float,struct ...)由于它们在堆栈中是实例化的,因此应该标记为assign。
如果你看到保留在一段代码中,那就是这个类没有使用ARC,它只是内存管理代码。
所有3个引用都指向同一个实例。
NSMutableArray *arr2=[arr1 retain];
。
增加引用计数并返回指向同一实例的指针(即self
)。
NSMutableArray *arr3 = arr1;
直接指定arr1
引用,而不通过任何方法调用。
唯一的区别是你在一个案例中增加了引用计数,而在其他情况下你没有。
分配参考的机制是相同的。通过在arr3 = arr1
上调用返回对自身的引用的方法,引用是直接(arr1
)还是间接引入并不重要。