Enum mit Pointern in C

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • macmoonshine schrieb:

    mattik schrieb:

    Klar geht das, aber wozu? Da holt man sich jede Menge Laufzeitoverhead und Namenskonventionen ins Boot, bei denen man nach drei Monaten wieder nachschauen muss, was man da angestellt hat - nur um sich eine Lookuptabelle zu ersparen? Hmmm...
    Ich sage ja nicht, dass es immer der optimale Weg ist. Allerdings juckt mir bei deiner Argumentation ein POITROAE in den Fingern, und dass eine Lookuptabelle wirklich schneller ist, sagt sich auch schnell daher. Die Namenskonventionen können nach drei Monaten Abstinenz sogar hilfreich sein. ;)
    Neenee, Geschwindigkeit war mir erstmal egal (obwohl ich glaube, dass ein Lookup in einem Dictionary wirklich schneller ist als Strings zusammenzusetzen und in der Runtime herumzustochern, aber wie gesagt egal). Ich will DRY, ich will KISS, ich will das kompakt, lesbar und konsistent an einer Stelle haben. Und ich will meinen Code so schreiben können, wie er sinnvoll ist und mich nicht durch selbst gemachte Vorgaben verbiegen müssen.

    Ich gehe von Marcos geschildertem Beispiel aus: Viele mögliche JSON-Keys parsen. Wenn ich eine Doku dazu schreiben müsste, würde ich das in einer Tabelle machen mit Key und der Bedeutung daneben. Genau so will ich das auch in meinen Code schreiben: Key und der passende Handler daneben (ich würde wohl Blocks nehmen, die dann eine aus einer Handvoll Handlermethoden mit passenden Argumenten aufrufen).

    Wenn ich das über gepre- oder postfixte Methoden machen würde, hätte ich da hundert Methoden stehen, von denen viele vermutlich ziemlich ähnlich aussähen. Die Methodennamen wären eine Mixtur aus ObjC-Konventionen (Camel Case) und den Konventionen der JSON-API. Und spätestens wenn einer der JSON-Spezifizierer so lustig war, Leer- oder andere lustige Sonderzeichen in die Keys zu packen, habe ich das ganz große Kino.

    Ich finde es toll, dass man sowas mit ObjC machen kann, aber in diesem Fall würde ich das halt nicht nutzen.
    Multigrad - 360°-Produktfotografie für den Mac
  • Amin Negm-Awad schrieb:

    Mir fällt jetzt die Erwiderung etwas schwer, denn das alles habe ich dem Kunden auch gesagt. Insbesondere waren dann Validierungsregeln schwierig zu formulieren und gingen so weit, dass wenn Schlüssel A den Wert X hat, dann muss der Schlüssel B existieren und so weiter. Ich sagte ihm dann: "Du kannst dir jetzt für die ganze Validierung eine DSL ausdenken, darin die Regeln formulieren und hast es dann sicher. Aber halt, du hast ja schon eine Sprache in der du die Regeln formulieren kannst: Objective-C. Wieso willst du also dir eine neue ausdenken, um das in Objective-C generisch zu formulieren und dann wieder in MySupiDupiDSL wieder zu konkretisieren?"

    Aber du sprichst es selbst an: Es gibt Grenzen. Bei Objective-Cloud können wir nicht applikationsspezifisch validieren. Logisch. Deshalb haben wir ja einen Compiler gebaut, der aus der Source wenigstens das herausholt, was drin steht. Ist ein Parameter etwa auf NSNumber* typisiert, darf da im JSON auch kein String stehen. Ist das auf Person* typisiert, darf da kein Gruppen-Objekt kommen usw. So würde man es ja auch innerhalb einer Applikation erwarten.

    Alles darüber hinaus könnte man jetzt sicherlich noch zu einem Gutteil mit irgendwas.config erschlagen können. Wollen wir nicht. Auf keinen Fall. Wenn es weitere Constraints gibt, sind die im Code zu schreiben. In der Sprache, die der Programmierer beherrscht: Objective-C.

    Alles andere ist Java.
    Ich will doch gar nicht die komplette Syntaxvalidierung mit irgendwelchem Zeug abstrahieren. Ich will keine Superduper-DSL, ich will ein Dictionary mit Keys und Handlern. Kann ja sein, dass es bei Objective-Cloud an bestimmten Stellen sinnvoll ist, Laufzeitdynamik zu nutzen, aber der geschilderte Fall ist halt ziemlich statisch: Keys und entsprechendes Verhalten sind vorher bekannt. Da kann man doch kompakt und leserlich an einer Stelle hinschreiben, was bei welchem Key passieren soll.

    Etwas wird nicht unbedingt dadurch schlecht, dass es jemand schonmal so ähnlich in Java geschrieben hat (gut: meistens schon, aber halt nicht immer).
    Multigrad - 360°-Produktfotografie für den Mac
  • mattik schrieb:

    Neenee, Geschwindigkeit war mir erstmal egal (obwohl ich glaube, dass ein Lookup in einem Dictionary wirklich schneller ist als Strings zusammenzusetzen und in der Runtime herumzustochern, aber wie gesagt egal). Ich will DRY, ich will KISS, ich will das kompakt, lesbar und konsistent an einer Stelle haben. Und ich will meinen Code so schreiben können, wie er sinnvoll ist und mich nicht durch selbst gemachte Vorgaben verbiegen müssen.
    Amin hat das Stichwort genannt: KVC. damit lassen sich wahrscheinlich 99% aller Fälle erschlagen, weil man in der Regel zunächst ja einfach die Werte speichern will.

    mattik schrieb:

    Ich gehe von Marcos geschildertem Beispiel aus: Viele mögliche JSON-Keys parsen. Wenn ich eine Doku dazu schreiben müsste, würde ich das in einer Tabelle machen mit Key und der Bedeutung daneben. Genau so will ich das auch in meinen Code schreiben: Key und der passende Handler daneben (ich würde wohl Blocks nehmen, die dann eine aus einer Handvoll Handlermethoden mit passenden Argumenten aufrufen).
    Ich gehe natürlich schon davon aus, dass die Anzahl der Keys fest ist. Bei meinem Vorschlag bräuchtest du übrigens nur eine neue Methode erstellen bzw. Property anlegen. Letzteres musst du bei deiner Lösung wahrscheinlich sowieso machen. Außerdem lässt sich bei meinem Vorschlag relativ einfach eine Kontextabhängigkeit der Schlüssel realisieren, die ja bei Baumstrukturen auch nicht gerade selten ist. Das Ganze sind vielleicht 20 Zeilen Code.

    Ob da dein Ansatz ein trockenes Küsschen oder eher doch feuchtes Geschlabber gegen ist? Das Anlegen von zig Blocks ist bestimmt nicht besonders gut lesbar, und wenn fast alle nur eine Property setzen müssen, wiederholst du dich recht oft.

    mattik schrieb:

    Wenn ich das über gepre- oder postfixte Methoden machen würde, hätte ich da hundert Methoden stehen, von denen viele vermutlich ziemlich ähnlich aussähen. Die Methodennamen wären eine Mixtur aus ObjC-Konventionen (Camel Case) und den Konventionen der JSON-API. Und spätestens wenn einer der JSON-Spezifizierer so lustig war, Leer- oder andere lustige Sonderzeichen in die Keys zu packen, habe ich das ganz große Kino.
    Ach verdammt! Dann nimm doch eben Swift! Da hast du deine gottlosen Sonderzeichen in Namen. ;) +scnr+ :D

    Ich gehe davon aus, dass an allen Enden des Entwicklertisches vernunftbegabte Menschen sitzen. Und wenn der JSON-Spezifizierer allerdings hart bleiben sollte, kann man ihn ja immer noch verspotten.
    „Meine Komplikation hatte eine Komplikation.“
  • gritsch schrieb:

    warum willst du die 500 keys überhaupt manuell abarbeiten?
    warum nicht einfach ein [setJsonValue: forKey:[NSNumber numberWithInteger:enumvalue]] ?

    "Wollen" ist gut…
    Es war ja nun nicht meine Idee, aus dem JSON Kram NSManagedObjects zu friemeln. Es war auch nicht meine Idee, den JSON Kram im JSON API Format zu definieren (wobei ich mich aktiv dafür eingesetzt habe – die Alternative war der Horror.)

    So ergab es sich, dass ich aus lustigen JSON Keypfaden NSManagedObject Werte machen musste.
    Und dabei viel mir auf, dass ich beispielsweise die 'data.attributes.date' und 'data.attributes.time' Keypfade an zwei unterschiedlichen Stellen abgefangen und bearbeitet habe.

    Trotz aller Dynamic mit Blocks und Co. muss ich immer noch tierisch aufpassen, den jeweiligen Keypath nicht zu überschreiben, denn sonst habe ich wieder denselben String doppelt vergeben.

    Nur lässt sich das in einem Dictionary natürlich ein wenig leichter nachvollziehen als in einer doppelt aufgetretenen If–Abfrage.

    Mein momentaner Ansatz macht es ungefähr so:

    C-Quellcode

    1. -(void)prepare {
    2. __block id me = self;
    3. _defaultBlock = ^( NSManagedObject * mo, NSString * keyPath, id value ){
    4. [mo setValue:value forKey:[me objectKeyForJSONKeyPath:keyPath]];
    5. };
    6. NSMutableDictionary * keyPathMappedBlocks = [NSMutableDictionary dictionaryWithCapacity:15];
    7. [keyPathMappedBlocks setObject:_defaultBlock forKey:@"data.id"];
    8. [keyPathMappedBlocks setObject:^( NSManagedObject * mo, NSString * key, id value ){
    9. [(NSDictionary *)value enumerateKeysAndObjectsUsingBlock:^(id _Nonnull attributeKey, id _Nonnull attributeValue, BOOL * _Nonnull stop) {
    10. [self setValue:attributeValue forKeyPath:[key stringByAppendingFormat:@".%@", attributeKey] forManagedObject:mo];
    11. }];
    12. } forKey:@"data.attributes"];
    13. [keyPathMappedBlocks setObject:_defaultBlock forKey:@"data.attributes.age"];
    14. // Adding mapping method for event attribute date
    15. [keyPathMappedBlocks setObject:^( NSManagedObject * mo, NSString * key, id value ){
    16. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    17. [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    18. NSDate *aDate = [dateFormatter dateFromString:value];
    19. [mo setValue:aDate forKey:[me objectKeyForJSONKeyPath:keyPath]];
    20. } forKey:@"data.attributes.date"];
    21. // …
    22. _keyPathMappedBlocks = keyPathMappedBlocks;
    23. }
    24. - (void)setValue:(id)value forKeyPath:(NSString *)keyPath forManagedObject:(NSManagedObject *)managedObject {
    25. // Remove ugly stuff from value if possible.
    26. if( [value respondsToSelector:@selector(stringByTrimmingCharactersInSet:)]) {
    27. value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    28. }
    29. // Avoid setting an empty value
    30. if( value == nil || ([value isKindOfClass:[NSString class]] && [value isEqualToString:@""]) ) {
    31. return;
    32. }
    33. // Get block from blockMappingDictionary…
    34. mappingBlock block = [_keyPathMappedBlocks objectForKey:keyPath];
    35. // Perform block if exists
    36. if( block != NULL ) {
    37. block( managedObject, keyPath, value );
    38. }
    39. // Otherwise output json key path which has no block stored for.
    40. else {
    41. NSLog( @"%@: No mapping found for key path «%@»", NSStringFromClass([self class]), keyPath );
    42. }
    43. }
    Alles anzeigen


    Zwei Hilfsmethoden –objectKeyForJSONKeyPath: und –jsonKeyPathForObjectKey: mappen die jeweiligen Keys und KeyPaths aus bereitgestellten Arrays, so dass ich da 'nur' an drei Stellen anpassen muss:
    – Key Array um den entsprechenden Property Key erweitern
    – KeyPath Array um den jeweiligen KeyPath erweitern
    – Handler für den jeweiligen KeyPath eintragen

    Wie gesagt schützt mich das nicht davor, das Setzen von 'data.id' 8x zu überschreiben.
    Gefällt mir optisch aber viel besser als die dusseligen If–Verschachtelungen oder Switch–Krankheiten.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • mattik schrieb:

    (das Set kann man dann ja trivial über [NSSet setWithArray:dict.allKeys] ableiten - warum gibt NSDictionary da eigentlich ein Array zurück?).
    Weil sich ein Set damals nicht alphabetisch aufsteigend sortieren ließ. ;)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P