保留和分配有什么区别

what is the difference between retain and assign

我搜索了很多链接并阅读了很多文章,但我找不到 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之间的区别?

如果上面的例子有误,请用更好的例子给出答案。

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

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

NSMutableArray *arr3 = arr1;
直接分配 arr1 引用,而不通过任何方法调用传递它。

唯一的区别是您在一种情况下增加了引用计数,而在其他情况下您没有。
分配引用的机制是相同的。引用是直接的 (arr3 = arr1) 还是间接的,通过在 arr1 上调用方法 returns 对自身的引用并不重要。

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

retainassign 是内存限定符的类型,但不影响底层对象是什么。具体来说,它们仅影响基础对象的 retainCount

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

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

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

NSMutableArray *arr2 = [arr1 retain];

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

NSMutableArray *arr3 = arr1; //Assign

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


"reference counting" 内存管理的基本游戏是确保:

  • 正在使用的对象具有正的保留计数(因此当您仍在使用它时它不会被释放)...未能正确执行此操作可能会导致对象被过早地释放,可能会给你留下悬空的引用;和

  • 您不再使用的对象将其 retainCount 减为零,因此当自动释放池耗尽时,该对象将被释放...无法递减正确位置的计数器可能会导致对象泄漏。

正如您所想象的,这会导致一个相当脆弱的过程,我们必须确保我们在 retainreleaseautorelease 中增加和减少我们的保留计数正确的地方。 Xcode 的 "static analyzer"(Xcode 的 "Product" 菜单上的 "Analyzer" 选项或按 shift+command+B) 在查看我们的代码并确定我们是否已正确完成此操作方面做得非常出色。如果你正在编写手动引用计数代码,这个工具是必不可少的。

但是,“automatic reference counting" is that we leave this silly world of incrementing and decrementing the object retainCount values behind us. We shift to a world where we can focus on the "object graph”的美妙之处在于,我们在代码的某些地方需要什么样的引用,编译器会为我们处理 retainCount 的递增和递减。

assignretain是objective-C.

中内存管理相关的2个策略

请看: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

无论如何调用一个对象的 retain 不会改变它的值,所以你会得到相同的输出是正常的。

retain / release objective-C 在 iOS 早期引入并推广的地方,当时苹果禁止 [=39= 使用 Garbage collector ] 由于性能问题而开发。由于缺少垃圾收集器,开发人员不得不在不再需要时手动处理对象销毁。因此,这是一个相当大的挑战,retain / release 是一种帮助开发人员更好地处理这个问题的方法。

从 iOS 5 开始,Apple 引入了 ARC(自动引用计数),它必须用于任何新开发,尤其是在您不熟悉内存管理的情况下。 ARC 允许开发人员停止使用保留/释放管理对象生命周期,因为在编译过程中添加了内存管理代码(即 [object retain][object release])。 开发人员在声明属性时只需关心内存管理:

@property(assign) int value;
@property(strong) id object;
@property (weak) id object;

在这种情况下,strong 和 retain 是相似的,可以互换。 strong 和 weak 只是新词,让初学者更容易理解幕后发生的事情。 此外,assign 假定为默认值,因此没有必要。

标记为强的 属性 将在 setObject 期间收到保留调用:标记为弱的 属性 将不会。由于retain只针对object(在Heap中实例化),基本C类型属性(bool, int, float, struct...),因为它们在Stack中实例化,应该标记assign.

如果你在一段代码中看到retain,那只是class没有使用ARC,它只是内存管理代码。