4

我想在枚举数组时将对象设置为“nil”,如下所示:

for(Object* object in array){
    object = nil;
}

然后 Xcode 告诉我“默认情况下,不能在 ARC 中修改快速枚举变量;声明变量 __strong 以允许这样做。

这意味着这样做:

for(Object __strong* object in array){
    object = nil;
}

这似乎是多余的。据我了解,声明对对象的强引用会将其保留计数增加一,而将其保留计数减少一。那么,如何nil在枚举数组时将对象设置为?

我正在使用 ARC。

4

3 回答 3

3

请参阅Clang“Objective-C 自动引用计数”文档中的快速枚举迭代变量:

如果在 Objective-C 快速枚举循环的条件下声明了一个变量,并且该变量没有明确的所有权限定符,那么它被限定为const __strong并且在枚举过程中遇到的对象实际上并没有被保留

基本原理
这是一种优化,因为快速枚举循环承诺在枚举期间保留对象,并且集合本身不能同步修改。可以通过用 显式限定变量来覆盖它__strong,这将使变量再次可变并导致循环保留它遇到的对象。

所以默认情况下,循环变量是不可变的,并且出于性能原因不会增加当前对象的保留计数。

如果将循环变量显式声明为__strong,则为可变强引用,增加当前对象的保留计数,将循环变量设置为nil再次减少保留计数。但这样做不会释放对象或将其从数组中删除,因为数组持有对该对象的另一个强引用。

于 2013-01-08T06:11:18.063 回答
2

一条捷径:

[array removeAllObjects];

如果您希望您的数组仍然包含 x 个项目,但不包含当前在其中的项目,您可以使用NSNull占位符:

for (NSUInteger i = 0; i < [array count]; i++)
    [array replaceObjectAtIndex:i withObject:[NSNull null]];

请记住,数组只保存对其对象的引用。如果数组不再持有对它们的引用,内存管理将启动并取消分配对象(但前提是其他任何事情都不做)。

于 2013-01-08T06:15:02.707 回答
0

在评论中,您已经透露,您的意图是释放数组中的对象,无论其他对象是否也对它们拥有所有权。这违反了核心内存管理原则:您不能释放不属于您的内存。做你想做的事是个坏主意。

必须允许其他对象管理自己的内存。数组中的一项可能是 UI 对象正在显示的一段数据。当 UI 对象需要刷新自身,并在其下查找已释放的数据时,您的应用程序可能会崩溃。

从这个数组的角度来看,您可以做两件事。您可以将数组作为一个整体解除分配,这将放弃数组对所包含对象的声明;如果它们不属于其他任何东西,它们将被释放。如果您想保留数组本身,但释放其所有项目,请使用removeAllObjects; 同样,如果没有其他人拥有这些项目,它们将被释放。

重要的一点是,如果其他东西确实拥有它们,那可能是有充分理由的,你不应该绕着它跑。

于 2013-01-10T20:19:12.953 回答