复制多维NSMutableArray

时间:2010-08-03 02:48:41

标签: objective-c cocoa-touch nsmutablearray nsarray nscopying

我目前正在开发数独应用程序,数字存储在NSNumbers的多维NSMutableArray中。我在我的SudokuGridView中保留一个数组,用于显示网格中的数字。当解决这个难题时,我将[grid numberGrid]传递给我创建的NSOperation的子类,解决了这个难题。

网格数组被定义为属性:

@property (readonly) NSMutableArray *numberArray; 

当它传递给数独网格解算器时,我去了:

MESudokuSolver *solvePuzzleOperation  = [[MESudokuSolver alloc] initWithPuzzle: [grid numberArray]];

initWithPuzzle定义如下:

- (id)initWithPuzzle:(NSMutableArray *)puzzleArray  {
    if(self = [super init]) {
        puzzle = [[NSMutableArray alloc] initWithArray: puzzleArray];
    }
    return self;    
}

然后我将拼图转换为原始的int数组来解决它,然后再回到拼图NSMutableArray。有趣的是,现在,网格的NSMutableArray现在有了解决方案......这意味着在MESudokuSolver内部以某种方式修改了网格的数组。所以我做了一些调查,传递到MESudokuSolver实例的数组的指针与MESudokuSolver的难题NSMutableArray不同。奇怪吧?我知道。

经过进一步调查,指向不同指针的数组内NSNumbers的指针实际上是相同的。

对于StackOverflow,我问,WTF?

1 个答案:

答案 0 :(得分:1)

使用另一个数组的内容初始化数组时,两个数组的内容将引用相同的对象。你想要做的是执行深层复制。这可以确保每个数组都引用它自己的对象副本,这样,如果在一个数组中修改对象,它就不会影响另一个数组中的对象,因为它们实际上是不同的对象。这甚至适用于数组数组。有许多方法可以执行深层复制。既然你想要在可变数组中使用可变数组的可变副本,那么它有点棘手,但很容易:

// Implemented as a free function here, but this is not required.

NSMutableArray *MECopyGrid(NSMutableArray *outer)
{
    NSMutableArray *result = [[NSMutableArray alloc] initWithCapacity:[outer count]];

    for (NSMutableArray *inner in outer)
    {
        NSMutableArray *theCopy = [inner mutableCopy];
        [result addObject:theCopy];
        [theCopy release];
    }

    return result;
}

还要注意NSNumber优化。 Cocoa(我还假设Cocoa Touch)缓存了一些不同的NSNumber实例。由于NSNumber实例是不可变的,如果您要求[NSNumber numberWithInteger:1],Cocoa可能会为您提供对包含相同值的现有实例的引用。如果您注意到NSNumber实例指针是相同的,那很可能是因为Cocoa已经为您提供了一个旧实例。这样可以节省内存,特别是在像你这样的情况下(没有优化你需要81个独立的NSNumber实例,但是你最多只需9个优化)。

相关问题