2011-04-19 55 views
1

我找不出是什麼原因造成的。基本上,一些不同的'任務'在我的應用程序中相互碰撞。當我按下一個按鈕,它運行這段代碼就好了:獲取「發送給不可變對象的變異方法」錯誤

PalAppDelegate *dataCenter = (PalAppDelegate *)[[UIApplication sharedApplication] delegate]; 




[dataCenter.colourPalettesContainer addObject:[NSNumber numberWithInt:5]]; 

因爲我喜歡它可以這樣做多次。但是,當我執行另一項任務(和那裏有一些這導致這種情況發生),其中涉及例如驗證碼:

PalAppDelegate *dataCenter = (PalAppDelegate *)[[UIApplication sharedApplication] delegate]; 

[dataCenter.colourPalettesContainer removeObjectAtIndex:touchDownID]; 

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 
[prefs setObject:dataCenter.colourPalettesContainer forKey:@"container"]; 
[prefs synchronize]; 

然後:

dataCenter.colourPalettesContainer = [prefs objectForKey:@"container"]; 

當我再次運行後的第一個代碼這會導致與「發送給不可變對象的變異方法」錯誤的崩潰。我怎樣才能阻止呢?

編輯:所以我從下面的一些答案中發現了問題。有沒有人有不同的做法,他們會建議?

+0

您的代碼嵌套太深,人類很難理解。我建議你把你的addObject語句分成5或10個子語句。那麼如果有什麼東西壞了,你就有機會找出它的位置。 – Rayfleck 2011-04-19 01:39:46

+0

它只是因爲我加入了保存到首選項行而已。它與我深深嵌套的Array沒有關係。我會從中刪除一些部分,以便於消化。 – Andrew 2011-04-19 01:41:19

+0

你說「當我在這之後再次運行第一個代碼時,它會崩潰」 - 意味着嵌套數組中的某處,對吧?所以問題是你不知道分配問題在哪裏。我經歷了許多痛苦的經歷,發現像這樣高度複雜的語句不會爲您節省任何編譯或執行時間,也不會使代碼更容易維護或調試,因此不值得花時間構建它們。我不是在批評,只是提供一些友好的建議。 – Rayfleck 2011-04-19 01:49:29

回答

6

NSUserDefaults返回一個不可變數組。你需要做的是一個可變的副本,當你加載備份:

NSMutableArray *mutableArray = [[prefs objectForKey:@"container"] mutableCopy]; 
dataCenter.colourPalettesContainer = mutableArray; 
[mutableArray release]; 

您可能還必須做陣列的內部的一些操作,因爲你在它裏面存儲NSMutableArrays。

+0

我認爲你是對的,因爲實現該代碼會在我的應用程序內導致一些非常奇怪的行爲。任何想法我需要在數組內做什麼樣的操作? – Andrew 2011-04-19 01:52:41

+0

我會切換它,讓你只持有不可變的對象,使其更簡單。對於數組,將它們作爲NSArrays而不是NSMutableArrays。然後,當您需要更改內容時,將其拉出,製作可變副本,添加/移除項目,然後將其添加回主陣列。我也可能會讓colourPalettesContainer成爲一個字典而不是數組。這樣你就可以記錄你的鑰匙的價值。您也可以根據密鑰進行替換,而不必擔心索引。對於這種情況,訂單並不重要。 – McCygnus 2011-04-19 02:44:36

+0

爲你+1,因爲它節省了我的時間,我不知道爲什麼出現這個問題,即使我的數組是一個可變數組.......... – Sabby 2011-05-19 10:33:45

2

NSUserDefaults總是返回不可變對象,即使您存儲的內容是可變的。要解決這個問題,你需要製作一個可變的副本。由於-mutableCopy返回調用者擁有一個對象,它需要(自動)發佈:

dataCenter.colourPalettesContainer = [[[prefs objectForKey:@"container"] mutableCopy] autorelease]; 

編輯)我張貼一些-mutableDeepCopy NSArray & NSDictionary methods而回,在回答另一個問題。如果你的問題涉及更深的嵌套收藏,並且你需要它們所有的都是可變的,這可能會有所幫助。

0

從一個陣列的特定索引中刪除一個對象。 (Swift 3.0)

let fullArray : NSArray = Userdefaults().value(forKey: "YOUR_ARRAY_STRING") as! NSArray 
var mutableArray : [AnyObject] = fullArray as [AnyObject] 
mutableArray.remove(at: INDEX_TO_REMOVE) //Eg: mutableArray.remove(at: 0) 
mutableArray.append(ARRAY_TO_APPEND) 
相關問題