Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c ObjC书内存管理说明与公文冲突_Objective C_Cocoa_Memory Management - Fatal编程技术网

Objective c ObjC书内存管理说明与公文冲突

Objective c ObjC书内存管理说明与公文冲突,objective-c,cocoa,memory-management,Objective C,Cocoa,Memory Management,我试图学习/理解在使用或创建各种对象时会发生什么以及为什么会发生。(希望从文档中学习。) 我正在读“Objective-C2.0中的编程”(第二版,由Steven Kochan编写)。在第408页,第一段讨论了保留计数: 请注意,其引用计数随后变为2。addObject:方法自动执行此操作;如果您查看文档中的addObject:方法,您将看到这里描述的事实 所以我读了addObject:docs: 在数组末尾插入给定对象 在那里,缺少描述,而其他项,如数组添加对象:,则说明它: 返回一个新数组,

我试图学习/理解在使用或创建各种对象时会发生什么以及为什么会发生。(希望从文档中学习。)

我正在读“Objective-C2.0中的编程”(第二版,由Steven Kochan编写)。在第408页,第一段讨论了保留计数:

请注意,其引用计数随后变为2。
addObject:
方法自动执行此操作;如果您查看文档中的
addObject:
方法,您将看到这里描述的事实

所以我读了
addObject:
docs:

在数组末尾插入给定对象

在那里,缺少描述,而其他项,如
数组添加对象:
则说明它

返回一个新数组,该数组是接收数组的副本,该数组的末尾添加了给定对象


在引用中,它在哪里表示
addObject:
增加了保留计数?考虑到ARC的存在,我仍然应该理解这些方法是如何避免错误和问题的。ARC带来了什么?(再看一遍…

这本书一定是指过时的文档,因为你是对的,它没有提到任何关于保留计数的内容。但它实际上保留了对象。您需要考虑的不是保留计数(这是无用的),而是所有权。尤其是使用ARC时

当您将一个对象添加到
NSMutableArray
时,它将获得该对象的所有权(在ARC术语中,它对该对象有很强的引用)

“ARC带来了什么?”

ARC没有什么不同。ARC所做的一切(除了一些优化)都是添加相同的release、retain和autorelease语句,您可以在不使用ARC的情况下添加这些语句。您需要关心的是,一旦您将对象添加到数组中,它的寿命至少与数组的寿命一样长


arrayByAddingObject:
方法将创建一个新的
NSArray
(或
NSMutableArray
)来包含要传递的对象,并保留对传递对象的强引用。它创建的实际数组对象还没有引用,除非将其指定给ivar、属性或局部变量。分配给它的内容决定了它的寿命


基本上,即使没有ARC,最好从所有权的角度来考虑对象生命周期,ARC只是将其形式化。因此,在使用框架时,无论何时发生或不发生保留,您只需对您的对象负责,直到您将所有权传递给另一个对象,并且您可以相信框架将在对象需要时保持对象的活动状态

当然,现在你必须凭直觉知道什么是所有权。例如,代理属性通常是
assign
,或在ARC
safe\u unrepaired
weak
中,以防止循环保留循环(其中两个对象彼此保留),尽管有时会保留/strong,因此您需要逐个查看这些循环

此外,在键值观察和NSNotification等情况下,观察您正在观察的对象不会保留观察者

但这些都是规则的例外。一般来说,您可以假设一个强引用

关于上面这句话:“它创建的实际数组对象还没有引用,除非您将其分配给ivar、属性或局部变量。您分配给它的内容决定了它的寿命。”我将尝试解释:

运行这段代码时:
[someArray arrayByAddingObject:someObject]
您已经实例化了一个新的
NSArray
NSMutableArray
对象(取决于
someArray
是哪种对象类型),但实际上尚未将其分配给任何引用。这意味着,如果您正在使用ARC,它可能会在之后立即释放,或者如果不使用ARC,它将在自动释放池耗尽时释放(可能在该线程的runloop的下一次迭代中)

现在,如果您这样做:
NSArray*someOtherArray=[someArray arrayByAddingObject:someObject]您现在有一个对新创建的数组的引用,称为someOtherArray。在本例中,这是一个局部变量,其作用域仅在它所驻留的
{
}
集合中(因此它可能位于
if
语句、循环或方法中。现在,如果您不对它做任何其他操作,它将在其作用域结束后的某个时间死亡)(它不能保证马上死亡,但这并不重要,你不能假设它活得更长)

现在,如果在类中的头中声明了一个iVar(实例变量),如
NSArray*someOtherArray;
(在ARC中默认为强),并且在类中的某个位置运行
someOtherArray=[someArray arrayByAddingObject:someObject];
,则该对象将一直存在,直到您删除引用为止(
someOtherArray=nil
),您将覆盖引用(
someOtherArray=someThirdArray
),或者该类被解除分配。如果您未使用ARC,则必须确保保留该类以达到相同的效果(
someOtherArray=[[someArray arrayByAddingObject:someObject]保留]
这基本上就是ARC在幕后所做的事情)

或者您可以声明一个属性,例如
@property(非原子,强)NSArray*someOtherArray
,其中
self.someOtherArray=[someArray arrayByAddingObject:someObject];
将实现相同的效果,但将使用适当的访问器(
setSomeOtherArray:
)或者您仍然可以使用
someOtherArray=[someArray arrayByAddingObject:someObject];
直接设置iVar(假设您
@合成了它)

或者假设没有AR