保留和分配[重复]之间有什么区别

问题描述 投票:1回答:3

这个问题在这里已有答案:

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

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

ios objective-c memory-management automatic-ref-counting reference-counting
3个回答
5
投票

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

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

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

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

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

NSMutableArray *arr2 = [arr1 retain];

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

NSMutableArray *arr3 = arr1; //Assign

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


“引用计数”内存管理的基本游戏是确保:

  • 正在使用的对象具有正保留计数(因此在您仍在使用它时不会释放它)...未能正确执行此操作可能会导致对象过早释放,可能会使您丢失引用;和
  • 你没有进一步使用的对象将retainCount减少到零,这样当自动释放池被耗尽时,对象将被释放...未能在正确位置递减计数器可能导致对象泄漏。

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

但是,“automatic reference counting”的美妙之处在于,我们离开这个愚蠢的世界,增加和减少我们身后的retainCount对象的价值。我们转向一个我们可以专注于“object graph”的世界,我们在代码中的某些地方需要什么样的引用,编译器负责为我们增加和减少retainCount


3
投票

assignretain是与Objective-C中的内存管理相关的两种策略。

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

无论如何,在对象上调用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
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.