在快速枚举期间将对象设置为nil

我想通过数组枚举一个对象为’nil’,如下所示:

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

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

这意味着这样做:

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

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

我正在使用ARC。

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

如果在Objective-C快速枚举循环的条件中声明变量,并且变量没有显式所有权限定符,则使用const __strong限定它,并且实际上不会保留枚举期间遇到的对象。

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

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

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

快捷方式:

 [array removeAllObjects]; 

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

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

请记住,该数组仅保存对其对象的引用。 如果数组不再包含对它们的引用,则内存管理将启动并释放对象(但仅在没有其他任何内容的情况下)。

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

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

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

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