2016-05-12 14 views
0

Ich habe ein UITabelView, das eine Liste von Elementen anzeigt (vom Server zurückgegeben), Benutzer können jedes Element auswählen und es seinem eigenen Bereich hinzufügen. Nach dem Auswählen eines Elements, ich die ausgewählten Elementdetails abrufen und speichern Sie es in eine PList-Datei, die Liste wird dann ein kleines Symbol anzeigen den Benutzer informiert, dass das Element zu seinem Abschnitt hinzugefügt wird. Der Benutzer kann es aus seinem Bereich entfernen, indem er erneut auf das Symbol klickt.containsObject gibt NO zurück, nachdem die App neu gestartet wurde

Um zu wissen, wenn der Artikel bereits in seinem Abschnitt ist, i

[self.myItemsArray containsObject:item] 

Alles perfekt arbeitet verwenden, wenn der Benutzer die Anwendung nicht verlassen. Das Problem tritt auf, sobald die App neu gestartet wird. Wenn ich die Tabellenansichtsliste von der Datenbank oder vom Server abruft, werden alle Elemente nicht wie in meiner Liste angezeigt und [self.myItemsArray containsObject: item] gibt NEIN für die zuvor hinzugefügten Elemente zurück.

Ich suchte nach einem alternativen Weg, indem ich ein NSArray meiner Artikel-IDs erstellte und dann überprüfe, ob das neue Array die Artikel-ID enthält, um das Symbol anzuzeigen. Das neue Problem ist, dass die ID vom Server doppelt zurückgegeben und so wie sie ist gespeichert wird. Die Anwendung abstürzt, wenn das Array zu erstellen:

[self.myItemsArray valueForKey:@"Id"] 

myItemsArray ist ein Array von Elementen (Artikel ist ein NSDictionary alle Details enthalten)

Also ich bin jetzt verzweifelt, könnte jemand mir helfen, indem die Lösung jeder die oben genannten Probleme? Ich bevorzuge die erste, da ContainsObject einfacher sein wird, aber ich habe nichts dagegen, es mit der zweiten Wahl zu lösen, wenn die erste nicht funktioniert.

+0

Speichern Sie die PLIST-Datei im Dateisystem, wenn Sie ein Element hinzufügen? Und lesen Sie beim Starten von app die PLIST-Datei erneut und bauen Sie 'self.myItemsArray' mit seinem Inhalt neu auf? – fullofsquirrels

+0

@fullofsquirrels genau, wenn ich die Liste vom Server abrufe, speichere ich die PLIST-Datei in den Dokumentenordner. Beim App-Start lese ich die PLIST-Datei und baue myItemsArray mit seinem Inhalt neu, zeige es in der UITableView an und führe einen Treffer aus, um den Inhalt vom Server zu aktualisieren. Auch ohne den neuen Trefferserver gibt containsObject NO zurück –

+0

Sind die Elemente? dass Sie in die plist-benutzerdefinierten Objekte einfügen, die Sie erstellt haben? Und wenn ja, wie sieht Ihre '-isEqual:' Methode aus?Für 'containsObject:' um zu arbeiten, besonders wenn Sie Objekte persistieren/aufheben, müssen Sie ein reproduzierbares Mittel haben um zu bestimmen ob zwei Objekte "gleich" sind – fullofsquirrels

Antwort

1

Sie werden sicherstellen müssen, dass Sie eine gute isEqual: Methode für Ihre benutzerdefinierte Klasse definiert haben, denn das ist, was NSArray Eindämmung zu bestimmen, verwendet: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/#//apple_ref/occ/instm/NSArray/containsObject:

ist diese Klasse so etwas wie ein ‚Schlüssel‘ Lassen Sie sagen, hat oder 'id' Wert, der für jede Instanz der Klasse eindeutig ist (was in Ihrem Fall ein double Typ ist). Dies wird natürlich nicht immer der Fall sein; es ist oft ein Aggregat einzelner Eigenschaften/Ivars, das einen einzigartigen "Schlüssel" darstellt, aber für die Zwecke dieser Diskussion sagen wir, dass ein solches Feld existiert. Der Code könnte wie folgt aussehen (alle in der .m):

static double const EPSILON = .000000001; // You'll need to be the judge of how "close" values can be to each other but still be distinct 

@interface MyObjectClass: NSObject 
@property (nonatomic, readonly) double uniqueKey; 
@end 

@implementation MyObjectClass 

// ... 

- (BOOL)isEqual:(id)object 
{ 
    if (self == object) { return YES; } 
    if (!object isKindOfClass:[MyObjectClass class]]) { return NO; } 

    MyObjectClass *myObject = (MyObjectClass *)object; 
    if (abs(self.uniqueKey - myObject.uniqueKey) < EPSILON) { return YES; } 
    return NO; 
} 

//... 

@end 

Beachten Sie, dass Sie sollten NICHT Prüfung für direkte Gleichheit zwischen zwei float oder double Werte; Eine gute Diskussion über die Fallstricke beim Arbeiten mit Gleitkomma- und Doppelpräzisionswerten finden Sie unter How dangerous is it to compare floating point values?.

+0

Vielen Dank für diese Erklärung :) –

Verwandte Themen