2010-08-03 74 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