iphone - mac - objective c tutorial deutsch




NSDictionary mit geordneten Schlüsseln (6)

Die Lösung, ein NSMutableArray von Schlüsseln zu haben, ist nicht so schlecht. Es vermeidet das Unterklassifizieren von NSDictionary, und wenn Sie mit dem Schreiben von Accessoren vorsichtig sind, sollte es nicht zu schwer sein, synchron zu bleiben.

Ich bin neugierig, ob dies eine Situation ist, in der sich andere Leute befinden. Ich habe ein NSDictionary (in einem Plist gespeichert), das ich grundsätzlich als assoziatives Array benutze (Strings als Schlüssel und Werte). Ich möchte das Array von Schlüsseln als Teil meiner Anwendung verwenden, aber ich möchte, dass sie sich in einer bestimmten Reihenfolge befinden (nicht wirklich eine Reihenfolge, in der ich einen Algorithmus schreiben kann, um sie zu sortieren). Ich könnte immer ein separates Array der Schlüssel speichern, aber das scheint irgendwie kludsey zu sein, weil ich immer die Schlüssel des Wörterbuchs sowie die Werte des Arrays aktualisieren und sicherstellen muss, dass sie immer übereinstimmen. Momentan benutze ich einfach [myDictionary allKeys], aber offensichtlich gibt dies sie in einer willkürlichen, nicht garantierten Reihenfolge zurück. Gibt es in Objective-C eine Datenstruktur, die mir fehlt? Hat jemand irgendwelche Vorschläge, wie man das eleganter macht?


Es gibt keine solche eingebaute Methode, von der Sie dies erwerben können. Aber eine einfache Logik funktioniert für dich. Sie können vor jeder Taste einfach einen numerischen Text einfügen, während Sie das Wörterbuch vorbereiten. Mögen

NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:
                       @"01.Created",@"cre",
                       @"02.Being Assigned",@"bea",
                       @"03.Rejected",@"rej",
                       @"04.Assigned",@"ass",
                       @"05.Scheduled",@"sch",
                       @"06.En Route",@"inr",
                       @"07.On Job Site",@"ojs",
                       @"08.In Progress",@"inp",
                       @"09.On Hold",@"onh",
                       @"10.Completed",@"com",
                       @"11.Closed",@"clo",
                       @"12.Cancelled", @"can",
                       nil]; 

Jetzt, wenn Sie sortingArrayUsingSelector verwenden können, während Sie alle Schlüssel in der gleichen Reihenfolge erhalten wie Sie.

NSArray *arr =  [[dict allKeys] sortedArrayUsingSelector:@selector(localizedStandardCompare:)];

An der Stelle, an der Sie Schlüssel in UIView anzeigen möchten, hacken Sie einfach die vorderen 3 Zeichen ab.


Ich mag C ++ nicht sehr, aber eine Lösung, die ich selbst mehr und mehr benutze, ist die Verwendung von Objective-C ++ und std::map aus der Standard Template Library. Es ist ein Wörterbuch, dessen Schlüssel beim Einfügen automatisch sortiert werden. Es funktioniert überraschend gut mit skalaren Typen oder Objective-C-Objekten, sowohl als Schlüssel als auch als Werte.

Wenn Sie ein Array als Wert NSArray , verwenden Sie einfach std::vector anstelle von NSArray .

Eine Einschränkung besteht darin, dass Sie möglicherweise Ihre eigene insert_or_assign Funktion bereitstellen insert_or_assign , es sei denn, Sie können C ++ 17 verwenden (siehe diese Antwort ). Außerdem müssen typedef Ihre Typen typedef , um bestimmte typedef zu vermeiden. Sobald Sie herausfinden, wie man std::map , iterators usw. verwendet, ist es ziemlich einfach und schnell.


Mein kleiner Zusatz: Sortierung nach numerischem Schlüssel (Kurzschrift für kleineren Code verwenden)

// the resorted result array
NSMutableArray *result = [NSMutableArray new];
// the source dictionary - keys may be Ux timestamps (as integer, wrapped in NSNumber)
NSDictionary *dict =
@{
  @0: @"a",
  @3: @"d",
  @1: @"b",
  @2: @"c"
};

{// do the sorting to result
    NSArray *arr = [[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];

    for (NSNumber *n in arr)
        [result addObject:dict[n]];
}

Schnell 'n dreckig:

Wenn Sie Ihr Wörterbuch bestellen müssen (hier "myDict" genannt), tun Sie Folgendes:

     NSArray *ordering = [NSArray arrayWithObjects: @"Thing",@"OtherThing",@"Last Thing",nil];

Erstellen Sie dann einen Index, wenn Sie Ihr Wörterbuch bestellen müssen:

    NSEnumerator *sectEnum = [ordering objectEnumerator];
    NSMutableArray *index = [[NSMutableArray alloc] init];
        id sKey;
        while((sKey = [sectEnum nextObject])) {
            if ([myDict objectForKey:sKey] != nil ) {
                [index addObject:sKey];
            }
        }

Jetzt enthält das * index-Objekt die entsprechenden Schlüssel in der richtigen Reihenfolge. Beachten Sie, dass diese Lösung nicht erfordert, dass alle Schlüssel notwendigerweise existieren, was die übliche Situation ist, mit der wir es zu tun haben ...


Wenn Sie NSDictionary ableiten, müssen Sie diese Methoden mindestens implementieren:

  • NSDictionary
    • -count
    • -objectForKey:
    • -keyEnumerator
  • NSMutableDictionary
    • -removeObjectForKey:
    • -setObject:forKey:
  • NSCopying / NSMutableCopying
    • -copyWithZone:
    • -mutableCopyWithZone:
  • NSCodierung
    • -encodeWithCoder:
    • -initWithCoder:
  • NSFastEnumeration (für Leopard)
    • -countByEnumeratingWithState:objects:count:

Der einfachste Weg, um das zu tun, was Sie wollen, ist, eine Unterklasse von NSMutableDictionary zu erstellen, die ihr eigenes NSMutableDictionary enthält, das sie bearbeitet, und ein NSMutableArray, um eine geordnete Menge von Schlüsseln zu speichern.

Wenn Sie Ihre Objekte niemals codieren, könnten Sie die Implementierung von -encodeWithCoder: und -initWithCoder: überspringen.

Alle Ihre Methodenimplementierungen in den obigen 10 Methoden würden dann entweder direkt durch Ihr gehostetes Wörterbuch oder Ihr geordnetes Schlüssel-Array gehen.







cocoa