2010-12-21 82 views
3

我有一個「doesNotRecognizeSelector」異常,我懷疑也許我的unarchiver返回不可變數組intstead intstead。 我對不對?我應該如何正確進行歸檔和歸檔? (例外的地方顯示)存檔可變陣列 - doesNotRecognizeSelector異常

謝謝!

NSMutableArray* arr; 

- (void) write 
{ 
     NSMutableData *data = [[NSMutableData alloc] init]; 
     NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] copy]; 
     [archiver encodeObject:copy forKey:@"Key"]; 
     [archiver finishEncoding]; 
     [data writeToFile:[Util DataPath] atomically:YES]; 
     [archiver release]; 
     [data release]; 
     [copyOfPaidPacks release]; 
} 




-(NSMutableArray*) read 
{ 
    NSString* DataPath = [Util FilePath]; 
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:DataPath]; 
    NSKeyedUnarchiver *unarchiver = nil; 
    if (data != nil) 
    { 
      unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; 

    if([self.Arr count] <= 0) 
    { 
     self.Arr = [unarchiver decodeObjectForKey:@"Key"]; 
    } 
} 

[unarchiver finishDecoding]; 
[unarchiver release]; 
[data release]; 
    return self.arr 
} 

-(void)B 
{ 
    [self write]; 
    NSMutableArray* SecondArr = [self read]; 
    [SecondArr sortUsingSelector:@selector(CompareDate:)]; - > `****THIS IS WHERE I GET THE EXCEPTION` 
} 
  • 編輯

添加比較方法:

- (NSComparisonResult)CompareDate:(T*)p 
{ 
    NSComparisonResult result = [self.changeDate compare:p.changeDate]; 
    if(result == NSOrderedDescending) 
     result = NSOrderedAscending; 
    else if(result == NSOrderedAscending) 
     result = NSOrderedDescending; 

    if(result == NSOrderedSame) 
    { 
     result = [self CompareName:p]; 
    } 

    return result; 
} 
+0

什麼是選擇它不承認?編輯:好吧,向下滾動,看看現在。你有沒有定義一個自定義的`CompareDate:`方法?另外,你的數組中有什麼樣的對象? – NSGod 2010-12-21 16:07:23

+0

我確定了它。我添加了代碼,以便您查看它。 – Idan 2010-12-21 20:55:19

回答

6

NSKeyedUnarchiver確實返回一個不可變NSArray。如果您確實想獲得NSMutableArray,則需要致電-mutableCopy,獲取decodeObjectForKey:的返回值。

這段代碼讓我懷疑你是否真的需要一個可變數組。看起來你只是對從-read得到的數組進行排序。爲什麼不直接在不可變的NSArray上調用sortedArrayUsingSelector:呢?

3

您已經將不可變數組傳遞給存檔器,那麼爲什麼您會期望unarchiver返回一個可變的數組呢?

如果你要一個副本是可變的,那麼你必須使用

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] mutableCopy]; 

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] copy]; 

將(至少就創建一個不變的副本,你應該予以關注。實際上,框架通常會爲不可變實例使用可變內部表示,但這是一個實現細節,您不應該依賴它,因爲這些表示在過去發生了變化,並且Cocoa文檔明確告訴您不檢查內部表示)。

編輯: 只需用的NSKeyedArchiver測試自己在iOS 5.0模擬器:

// this returns a mutable instance at runtime! 
NSMutableArray* test0 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[NSMutableArray array]]]; 
// this returns an immutable instance at runtime! 
NSArray* test1 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[NSArray array]]]; 

所以你的問題真的僅僅通過複製而不是mutableCopy引起的,而封存和解除封存保留的正確的易變性的屬性實例!

0

我有一個問題,即歸檔一個3維可變數組(即,可變數組的可變數組的可變數組)將作爲不可變數組的不可變數組的可變數組解決。

的關鍵,固定,這是子類NSKeyedUnarchiver並覆蓋

- (Class)classForClassName:(NSString *)codedName 
{ 
    Class theClass = [super classForClassName: codeName]; 

    if ([codeName isEqualToString: NSStringFromClass(NSArray.class)) 
    { 
     theClass = NSMutableArray.class; 
    } 
    //... more here like NSDictionary 
    return theClass; 
}