2010-12-21 10 views
3

Ich habe eine "doesNotRecognizeSelector" -Ausnahme und ich vermute, dass meine unarchiver möglicherweise unveränderlichen Array anstelle von veränderbar zurückgeben. Bin ich richtig? Wie sollte ich die Archivierung und Archivierung richtig machen? (Ort der Ausnahme ist Showdown)Mutable-Array archivieren - doesNotRecognizeSelector-Ausnahme

Danke !!!

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` 
} 
  • bearbeiten

die Methode vergleichen Hinzufügen:

- (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

überschreiben Was wird der Wähler es nicht erkennt? EDIT: Okay, scrollte runter und sieh jetzt. Haben Sie eine benutzerdefinierte 'CompareDate:' Methode definiert? Welche Arten von Objekten befinden sich in Ihrem Array? – NSGod

+0

Ich habe es definiert. Ich habe Code hinzugefügt, damit Sie es überprüfen können. – Idan

Antwort

6

NSKeyedUnarchiver in der Tat eine unveränderliche NSArray zurückgibt. Wenn Sie wirklich eine NSMutableArray erhalten möchten, müssen Sie -mutableCopy auf den Rückgabewert von decodeObjectForKey: aufrufen.

Dieses Code-Snippet lässt mich fragen, ob Sie wirklich ein veränderbares Array benötigen. Es sieht so aus, als ob Sie nur das Array sortieren, das Sie von -read erhalten. Warum nicht einfach sortedArrayUsingSelector: auf dem unveränderlichen NSArray aufrufen?

+0

Ich nahm an, dass es veränderbar sein muss, um sortiert zu werden, weil das Sortieren nach der Definition die Position von Objekten im Array verändert. (was Hinzufügen und Entfernen bedeutet). Liege ich falsch ? – Idan

+1

@Idan: Sie können keine * In-Place * -Sortierung für ein unveränderliches Array durchführen, aber Sie können jedes Array nach einer Version seiner selbst fragen, sortiert nach einem bestimmten Selektor (oder Funktion), mit 'sortedArrayUsingSelector:' von kperryua. – Chuck

+0

Ok ich bekomme es, also wie erklären Sie die unerkannte Selektor Ausnahme? Das komische daran ist, dass es meistens funktioniert. irgendeine Idee ? – Idan

3

Sie übergeben bereits ein unveränderbares Array an den Archiver, also warum sollten Sie erwarten, dass der Unarchivierer dann einen veränderlichen zurückgibt?

Wenn Sie eine Kopie sein wandelbar wollen, dann müssen Sie verwenden

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

als

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

wird eine unveränderliche Kopie erstellen (zumindest so weit, wie Sie betroffen sein sollten. In Wirklichkeit verwendet das Framework häufig eine veränderbare interne Repräsentation für unveränderliche Instanzen, aber dies ist ein Implementierungsdetail und Sie sollten sich nicht darauf verlassen, da sich diese Repräsentationen in der Vergangenheit geändert haben und die Cocoa Dokumente Ihnen explizit sagen, nicht nach dem zu suchen interne Repräsentation).

EDIT: nur mit NSKeyedArchiver mich auf 5,0 iOS Simulator getestet:

// 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]]]; 

So Ihr Problem wirklich ausschließlich durch die Verwendung Kopie statt mutableCopy verursacht wird, während von Archiven, das richtige Veränderlichkeit-Attribut der halten Instanzen!

0

Ich hatte ein Problem, bei dem die Archivierung eines 3-dimensionalen veränderbaren Arrays (dh eines veränderbaren Arrays veränderbarer Arrays aus veränderbaren Arrays) als veränderbares Array unveränderlicher Arrays unveränderlicher Arrays entschlüsseln würde.

Der Schlüssel zur Festsetzung war NSKeyedUnarchiver Unterklasse und

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

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