2010-08-03 115 views
1

我目前正在研究数独应用程序,数字存储在NSNumbers的多维NSMutableArray内。我在SudokuGridView中保存一个数组,用于在网格中显示数字。当需要解决这个难题时,我将一个[gridGridGrid]传递给我创建的NSOperation的子类,以解决这个难题。复制多维NSMutableArray

网格的阵列被定义为一个属性为这样的:

@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;  
} 

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

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

给你StackOverflow,我问,WTF?

回答

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 Touch也可以)缓存几个不同的NSNumber实例。由于NSNumber实例是不可变的,如果你要求[NSNumber numberWithInteger:1],Cocoa可能会给你一个包含相同值的现有实例的引用。如果你注意到NSNumber实例指针是相同的,那很可能是因为Cocoa给了你一个旧实例。这样可以节省内存,特别是在像你这样的情况下(没有优化,你需要81个独立的NSNumber实例,但优化最多只需要9个)。

+0

谢谢!我从来没有真正遇到过这个问题,可能是因为我以前从未使用多维NSArrays。 如果我可以问一个简单的问题来澄清这里...为什么如果你有一个一维数组...说NSStrings,那些字符串实际上是复制在内存中,而不是直接从另一个实例修改? – 2010-08-04 00:31:42

+0

@Matt Egan:我不完全确定你的意思。如果你有一个不可变的字符串数组,它们可能永远不会被复制到内存中。由于没有任何东西可以修改不可变的字符串,所以'copy'就变成了简单的'retain'。如果您创建包含不可变字符串的数组副本,则两个数组都将包含对相同不可变字符串的引用。修改对象唯一值得关注的问题是数组包含* mutable *对象。如果你想要一个对象保持可变,但你不想改变它,你必须得到一个'mutableCopy'。 – dreamlax 2010-08-04 20:53:53

+0

这是总的感觉,再次感谢! – 2010-08-05 01:52:45