Ce .location me tracasse

ideaidea Membre
01:54 modifié dans API AppKit #1
J'ai adapté un exemple de filtrage de TableView par searchField que j'ai remplacé par un pop up. Exemple que j'ai trouvé ici :
http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Tasks/filtering.html
Tout fonctionne bien mais y'a  un truc que je comprends pas c'est le .location dans ce bout de code :
if ([[item valueForKeyPath:@"category"] rangeOfString:filterString options:(NSAnchoredSearch && NSCaseInsensitiveSearch)].location != NSNotFound)

Quelqu'un pourrait il eclairer ma lanterne?
merci

Réponses

  • schlumschlum Membre
    01:54 modifié #2
    typedef struct _NSRange {<br />   unsigned int location;<br />   unsigned int length;<br />} NSRange;
    


    - (NSRange)rangeOfString:(NSString *)aString
    


    Return Value

    An NSRange structure giving the location and length in the receiver of the first occurrence of subString. Returns {NSNotFound, 0} if subString is not found, is the null string, or is empty.
  • ideaidea Membre
    01:54 modifié #3
    Donc si j'ai bien compris, la méthode rangeOfString renvoie une struct NSRange et j'obtiens la 'location' de ce range en ajoutant .location. et J'aurai pu obtenir lentgth avec .length. C'est Ca?
    C'est du C de base, non? faut dire que depuis que je me suis mis a l'objective C, j'ai un peu oublié mes maigres connaissances en C.
    Merci en tout cas.
  • schlumschlum Membre
    01:54 modifié #4
    dans 1176892025:

    Donc si j'ai bien compris, la méthode rangeOfString renvoie une struct NSRange et j'obtiens la 'location' de ce range en ajoutant .location. et J'aurai pu obtenir lentgth avec .length. C'est Ca?
    C'est du C de base, non? faut dire que depuis que je me suis mis a l'objective C, j'ai un peu oublié mes maigres connaissances en C.
    Merci en tout cas.


    C'est exactement ça...
    (et c'est effectivement du C... Comme NSPoint, NSSize, NSRect et d'autres...)
  • ideaidea Membre
    01:54 modifié #5
    le truc c'est que dés que je vois NSTruc, je pense objet. J'ai tellement lu a droite et a gauche qu'il fallait penser objet pour progammer objet...
  • schlumschlum Membre
    avril 2007 modifié #6
    Certaines fonctions C commencent par NS aussi  ;)

    NSMakeRect par exemple ou NSBeginAlertSheet (et beaucoup d'autres...)

    NS veut dire "NeXTSTEP", du nom de l'OS éponyme créé par la société NeXT Software Inc. fondée par Steve Jobs ; société qui a inventé l'ancêtre de Xcode (et popularisé l'Objective-C...), et rachetée par Apple.
  • AliGatorAliGator Membre, Modérateur
    avril 2007 modifié #7
    C'est vrai que c'est déroutant de voir parfois qu'on en retourne au C et aux structures pour des "objets" (qui n'en sont donc pas au sens Obj-C & NSObject du terme, justement), comme pour NSRect, NSPoint, NSRange...

    D'un côté dans un sens c'est logique, car pourquoi faire un objet Objective-C quand une structure "pur C" existe, et que du coup à  la compilation et l'interprétation c'est plus rapide (ne passe pas par la procédure d'envoi de messages, etc).
    Mais d'un autre ça "brise un peu la cohérence" avec tout ce dont on a l'habitude puisque comme tu dis on nous conseille (à  raison) de penser plus "objet" en Objective-C... donc ces structures comme NSRange viennent un peu "casser l'ambiance" :P

    Je trouvais ça dommageable pour la cohérence du code, au début... mais finalement on s'y fait et il n'y en a pas tant que ça de NSChose qui sont en fait des structures donc on a vite fait de les connaà®tre (y'a au moins NSPoint, NSSize, NSRect, NSRange, et j'en oublie qques unes mais sans doute pas des masses) :)
  • schlumschlum Membre
    01:54 modifié #8
    Ca dépend... Si tu ne comptes que Foundation, il n'y en a pas énormément...
    NSAffineTransformStruct, NSPoint, NSSize, NSRect, NSHashTable, NSMapTable, NSRange, NSZone
    (sans compter les "private" et les sans intérêt...)

    Mais dans l'ensemble des Frameworks, il y en a une grosse quantité. Ca ne me choque pas, le C fait partie intégrante de l'Objective-C et ces sturctures n'empêchent pas de penser objet.
    Ce qui me gêne beaucoup plus, c'est que Cocoa ne sait pas par défaut archiver ces types (et le faire soi-même de manière endian-safe etc. est un vrai casse-tête !)
    Pour un patch assez laid -> http://forum.macbidouille.com/index.php?showtopic=175894
  • 01:54 modifié #9
    Il existe des constructeurs de NSValue pour les structures principales utilisées dans Cocoa (Point, Rect, Size, Range)
  • schlumschlum Membre
    avril 2007 modifié #10
    dans 1176937920:

    Il existe des constructeurs de NSValue pour les structures principales utilisées dans Cocoa (Point, Rect, Size, Range)


    Yep, mais essaie de les archiver après avec NSKeyedArchiver  ;)
    ->
    [NSKeyedArchiver encodeValueOfObjCType:at:] this archiver cannot encode structs
  • 01:54 modifié #11
    [aKeyedArchiver encodeObject:[NSValue valueWithPoint:aPoint] forKey:@point];

    Je dis ça je dis rien.
  • schlumschlum Membre
    01:54 modifié #12
    dans 1176942066:

    [aKeyedArchiver encodeObject:[NSValue valueWithPoint:aPoint] forKey:@point];

    Je dis ça je dis rien.

    Oui, mais non...  :P

    Petit projet de démonstration :

    #import &lt;Foundation/Foundation.h&gt;<br /><br />int main (int argc, const char * argv&#91;]) {<br />&nbsp; &nbsp; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br />	<br />	NSMutableData *data = [[NSMutableData alloc] init];<br />	NSKeyedArchiver *aKeyedArchiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];<br />	[aKeyedArchiver encodeObject:[NSValue valueWithPoint:NSMakePoint(1.,-5.)] forKey:@&quot;point&quot;];<br />	[aKeyedArchiver release];<br />	NSLog([data description]);<br />	[data release];<br />	<br />&nbsp; &nbsp; [pool release];<br />&nbsp; &nbsp; return 0;<br />}
    


    -> Crash
    2007-04-19 02:29:15.012 Tool[1514] *** Uncaught exception: <NSInvalidArgumentException> *** -[NSKeyedArchiver encodeValueOfObjCType:at:]: this archiver cannot encode structs
  • 01:54 modifié #13
    Sympa comme truc, ils font une classes qui est normalement conforme à  NSCoding et puis ça ne va pas. Mais de toute façon, j'avais une solution de rechange: les fonctions NSStringFromPoint/NSPointFromString (+ les autres types évidemment).
  • schlumschlum Membre
    avril 2007 modifié #14
    dans 1176970260:

    Sympa comme truc, ils font une classes qui est normalement conforme à  NSCoding et puis ça ne va pas. Mais de toute façon, j'avais une solution de rechange: les fonctions NSStringFromPoint/NSPointFromString (+ les autres types évidemment).

    Yep... Sympa... Surtout que ça fonctionnait avec les NSArchiver / NSUnarchiver qui sont deprecated maintenant... (et beaucoup moins pratiques surtout)  :-\\
    D'où la technique explicitée dans le lien ci-dessus de mettre un NSData obtenu avec un NSArchiver...

    Pour le passage par NSString, pas fan...
  • schlumschlum Membre
    01:54 modifié #15
    D'ailleurs, les version "Keyed" de NSArchiver et NSUnarchiver apportent un confort certain, mais on a perdu quelques fonctions très pratique pour l'encodage de données "C" :
    "encodeValueOfObjCType" et "decodeValueOfObjCType" qui existent dans NSCoder et ne sont pas implémentées dans les "Keyed"

    En gros, maintenant c'est "débrouillez vous avec vos structures C"...

    Espérons qu'ils travailleront dessus pour 10.5  ::)
  • AliGatorAliGator Membre, Modérateur
    01:54 modifié #16
    dans 1176934923:
    Ce qui me gêne beaucoup plus, c'est que Cocoa ne sait pas par défaut archiver ces types (et le faire soi-même de manière endian-safe etc. est un vrai casse-tête !)

    dans 1176939153:
    Yep, mais essaie de les archiver après avec NSKeyedArchiver  ;)
    ->
    [NSKeyedArchiver encodeValueOfObjCType:at:] this archiver cannot encode structs

    Hello...

    Je suis pas sûr de suivre toutes vos réactions : je n'ai pas testé, mais pour moi, d'après la doc on a :

    1) A lire : doc Apple pour archiver des struct (en résumé il suffit d'archiver champ par champ, et tu n'as aucun problème d'endianness si tu fais comme ça. Avec les méthodes genre [tt]encodeInt:forKey:[/tt] et consoeurs, tu t'en sors facilement pour encoder tes champs)

    2) Regarde la doc de NSValue (qui permet d'encapsuler des struct utilisées dans Cocoa dans un objet comme l'indique Renaud) : comme NSValue est un NSObject qui se conforme au "NSCoding protocol", on peut le sérialiser dans une archive en le passant à  [tt]encodeObject:forKey:[/tt] du coup !

    3) Et enfin, pour ces structures particulières de Foundation, il y a tout ce qu'il faut dans NSCoder : encodePoint:, encodeRect:, etc (et leurs équivalents ...forKey:) !

    Donc je pense pas qu'il y ait de souci tant pour archiver des Point, Rect, Range & co que pour des structures personnalisées, si ? J'ai loupé un truc qui pose problème ?
  • schlumschlum Membre
    01:54 modifié #17
    dans 1177008771:

    1) A lire : doc Apple pour archiver des struct (en résumé il suffit d'archiver champ par champ, et tu n'as aucun problème d'endianness si tu fais comme ça. Avec les méthodes genre [tt]encodeInt:forKey:[/tt] et consoeurs, tu t'en sors facilement pour encoder tes champs)


    Très pratique pour encoder des tableaux... Une clé par indice  :o


    2) Regarde la doc de NSValue (qui permet d'encapsuler des struct utilisées dans Cocoa dans un objet comme l'indique Renaud) : comme NSValue est un NSObject qui se conforme au "NSCoding protocol", on peut le sérialiser dans une archive en le passant à  [tt]encodeObject:forKey:[/tt] du coup !


    Regarde les tests au dessus ; ça ne fonctionne pas, c'est ce qui est reproché.


    3) Et enfin, pour ces structures particulières de Foundation, il y a tout ce qu'il faut dans NSCoder : encodePoint:, encodeRect:, etc (et leurs équivalents ...forKey:) !


    Dans une de mes applications, j'ai plusieurs structures perso que j'encapsule dans des NSValue avec une catégorie... Au moment de sauvegarder ces NSValues, ça a été la croix et la bannière.
Connectez-vous ou Inscrivez-vous pour répondre.