@synthesize, @dynamic oder doch etwas anderes?

  • @synthesize, @dynamic oder doch etwas anderes?

    Hallo,

    folgende Frage: Ich habe eine Property namens "tag", die sich als Zahlenwert aus verschiedenen anderen Properties berechnet. Für diese Property habe ich einen getter angelegt, der nur den berechneten Wert zurückliefert, aber nicht speichert. Es gibt keine Instanzvariable zu dieser Property.

    Nun versuche ich mit folgendem Aufruf ein Array zu filtern:

    Quellcode

    1. NSNumber *tag = ...
    2. [... filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"tag == %@", tag]]

    Allerdings bleibt das Ergebnis-Array leer, obwohl sicher gestellt ist, dass tag einen gültigen Wert enthält, der zumindest zu einem Objekt als Ergebnis führen müsste.

    Liegt es daran, dass ich tag mit @synthesize synthetisiere? Hätte ich @dynamic oder irgendwas anderes oder gar nichts verwenden müssen?

    ich frage auch deshalb - und mache nicht trial-and-error - weil ich die Unterschiede zwischen @synthesize und @dynamic noch nicht kapiert habe und auf eine kurze Erklärung hoffe.

    Danke!!
  • fwtag schrieb:

    Liegt es daran, dass ich tag mit @synthesize synthetisiere? Hätte ich @dynamic oder irgendwas anderes oder gar nichts verwenden müssen?

    @synthesize legt zu der Property ein Attribut an. Die neueren Compiler fügen automatisch ein @synthesize ein, wenn Du es nicht machst. Wenn Du das Attribut nicht brauchst, solltest Du das durch ein @dynamic verhindern. (Besser ist das ;))
    „Meine Komplikation hatte eine Komplikation.“
  • Wenn du eine property ohne passende Instanzvariable hast ist ein @synthesize auf jeden Fall nicht das richtige - der erzeugt die Accessor-Methoden und fügt eine Instanzvariable ein, falls es noch keine passende gibt. Wenn du händisch getter bzw. setter baust, brauchst du weder ein @synthesize noch ein @dynamic.

    @dynamic ist eigentlich für den Fall, dass es keine statischen Accessoren (weder automatisch noch händisch) gibt, sondern die Accessor-Nachrichten dynamisch zur Laufzeit abgefangen werden sollen (respondsToSelector:, performSelector: usw). @dynamic ist also eher ein Hinweis für den Compiler, dass es zur Übersetzung keine Accessoren gibt und das auch beabsichtigt und richtig ist.

    Bei properties ohne Instanzvariablen, wie du sie beschrieben hast, tippe ich eher auf ein anderes Problem: KVO. Properties (auch readonly) sollten sich nie ändern ohne dass die entsprechenden willChangeValueForKey- und didChangeValueForKey-Methoden aufgerufen werden, sonst geht das ganze Property- und KVO-Zeug kaputt.
    Multigrad - 360°-Produktfotografie für den Mac
  • Ich habe es mal auf @dynamic geändert, hat aber leider auch nichts gebracht.

    KVO ist für mich an dieser Stelle nicht interessant. Ich möchte nur aus einem Array ein Objekt auswählen, dass das gewünschte tag aufweist, das ich aööerdings on-the-fly erzeuge. Ich habe auch gesehen, dass die tag-Methode (bzw. der Pseudo-Getter) angesprungen wird. Aber trotzdem gibts kein Ergebnis. :(

    EDIT:
    Achso - tag ist vom Typ NSUinteger. Mage es daran liegen dass es scheitert?
  • mattik schrieb:

    Wenn du händisch getter bzw. setter baust, brauchst du weder ein @synthesize noch ein @dynamic.

    Außer Du möchtest das Attribut über @synthesize anlegen. ;)

    Damit gibt es bei den neueren Compilern also einen Unterschied zwischen automatischen und manuellen @synthesize: Letzteres legt immer eine iVar an, erstere nur, wenn mindestens auch ein Accessor synthetisiert wird.
    „Meine Komplikation hatte eine Komplikation.“
  • Komisches Ding. Ich habe nun - mangels Erfolg - das Filtern über die tag-Property durch ein Filtern über die anderen drei beteiligten Properties ersetzt (die je synthtisiert sind und "echte" ivars haben) und damit geht es. Aber es ist eigentlich nicht ganz das, was ich gern will.

    Ich weiß nicht, was hier falsch läuft.

    Edit:
    Hab das nun anders (und eleganter) mit enumeratObjecsUsinBlock: gelöst, denn eigentlich suche ich ohnehin nur das erste Auftreten des Objekts.
  • Schau dir mal deine Code in #1 an

    Quellcode

    1. NSNumber *tag = ...
    2. [... filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"tag == %@", tag]]


    Das ist tag bei mir ein NSNumber und selbst wenn es ein NSUInteger wäre, dann müßte der Predicate String eben "tag = %ld" heissen und nicht "tag= %@"

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Anders als andere hier schreibe ich nicht jeden iterativen Testschritt hier auf. Ich habe Deine Anregung, es mit %ld zu versuchen, wahrgenommen. Vorher hab ich es auch schon mit %d probiert, da ja, wie gesagt, tag vom Typ NSUInteger ist.

    Alles in Allem bleibt das Problem bestehen, dass offenbar (bei mir) eine computed property nicht mit filteredArrayUsingPredicate: funzt. Der andere Ansatz geht aber.
  • fwtag schrieb:

    Anders als andere hier schreibe ich nicht jeden iterativen Testschritt hier auf. Ich habe Deine Anregung, es mit %ld zu versuchen, wahrgenommen. Vorher hab ich es auch schon mit %d probiert, da ja, wie gesagt, tag vom Typ NSUInteger ist.

    Alles in Allem bleibt das Problem bestehen, dass offenbar (bei mir) eine computed property nicht mit filteredArrayUsingPredicate: funzt. Der andere Ansatz geht aber.


    Tut mir leid aber wenn da steht

    NSNumber *tag...

    und in der nächsten Zeile wird tag dann benutzt, wie soll man sich denn dann denken das Du dazwischen noch aus tag ein NSUInteger machst?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)