listes chaînées en Objective-C

@mala
Par contre sous Xcode, via le débogueur, lorsque j'ouvre mon fichier, le nombre d'octets chargés est le bon (ouf), mais je n'arrive pas à voir en mémoire son contenu. Lorsque je déroule l'objet NSData, il y a un pointeur "isa" et puis c'est tout. Même si je demande à voir le contenu du pointeur, je n'ai pas les bonnes données visiblement. Je ne vois pas où sont stockés les octets lus.
En fait, il faut bien intégrer qu'Obj-C est un langage dynamique (les accès aux variables d'un objet ou même d'une méthode sont ainsi calculés à la volée contrairement à des langage statics comme Java ou C++). Mais du coup, tu ne peux pas toujours dérouler aussi facilement (notamment pour les classes dont tu n'as pas le source) le contenu d'un objet comme tu le ferais avec une instance C++ par exemple. C'est une des spécificités d'Obj-C qui lui confère une grande puissance mais bref on pourra y revenir si tu as des questions.
Pour récupérer ton buffer dans ton cas, utilises la méthode "bytes".
Bloc de code:
const char *buf = (const char*)[monObjetNSData bytes];
la méthode "bytes" retournant un "const void *", on cast le retour de la méthode en fonction du format désiré (8bits,16bits,signé, pas signé, etc) pour éviter un warning.

Tu peux aussi utiliser des méthodes telles que..
Bloc de code:
- (void)getBytes:(void *)buffer range:(NSRange)range
...pour récupérer des copies de portions de ton buffer si tu préfères.

A noter que si tu voulais pouvoir modifier ton buffer (mais je pense pas que ce soit le cas ici), tu te tournerais vers NSMutableData qui dispose d'une méthode "mutableBytes". Laquelle retourne un "void*" (donc modifiable).

Donc pour la parenthèse, en Obj-C on fait toujours la distinction entre objets "en lecture seule" et objets modifiables.
Exemple de classes:
NSString et NSMutableString.
NSArray et NSMutableArray.
NSDictionary et NSMutableDictionary.
etc.

Sinon, venant du C/C++/C#, l'Objective-C n'est pas si méchant une fois le nez dedans.
Tout a fait. Le tout est d'intégrer les quelques rudiments qui vont bien pour partir du bon pied et après c'est pas sorcier.

Pour parcourir plus rapidement les classes Obj-C qu'avec l'aide d'xcode, je te conseille l'excellent AppKiDo. Bien sûr au début le problème c'est qu'il faut savoir ce qu'on cherche :D mais tu verras qu'à l'usage sa présentation hiérarchique des classes et sa recherche rapide sont très pratiques.

Edit: je viens d'y penser mais si tu codes sous PPC, ne pas oublier que la lecture de fichiers binaires peut être impacté par l'architecture processeur (tu avais l'air de sous entendre que ton fichier venait d'un PC si je ne m'abuse). Il peut donc y avoir nécessité de réordonner les octets lus.
 
  • J’aime
Réactions: tatouille
obsolète concernant obj-c 2

dsl j'ai répondu rapidement c'était à prendre comme une note bien sur qu'en obj-c v2 tu peux compiler
en gardant l'option, c'est juste pour quelq'un qui donne comme exemple le cplusplus, et qu'on lui propose un language objet avec des retain et des release (alloc free) cela peut paraitre assez bizarre et assez chiant, la nouvelle donne :
AUTO-MEM qui est bien meilleur que celle du c++ qui parfois peu devenir une horreur , car oui un language qui cache les systemcalls cela peut paraitre + confortable , mais à l'utilisation c'est souvent le contraire , enfin cela dépend ce que l'on fait , c'est pour cela que je suis devenu un D afficionados

:zen:

l'OBJ_C pourrait se résumer par getElementByID hop un sample tout chaud

PS : je vois que mon nouvel avatar à du succès :D
coucou.gif
c'est un hommage à la plus belle pair de seins de macgé ( accéssoirement elle plonge :D en mer chaude, si un jours, elle est au courant de ce commentaire je saurais que cela vient de l'un d'entre vous car je ne pense pas qu'elle descende aussi profond :D )


ca dépend du PC , si cela provient d'un NIX aucun problème there are all bigendian
 
  • J’aime
Réactions: p4bl0
dsl j'ai répondu rapidement c'était à prendre comme une note bien sur qu'en obj-c v2 tu peux compiler
en gardant l'option,
Y a pas de mal. ;)
C'est le terme "obsolète" qui m'a fait réagir car le raccourci était un peu rapide. Il y a deux raisons majeures à cela:
- Les GC sont loin d'être la solution miracle en terme de performances/gestion des ressources.
- C'était faire un peu vite l'impasse sur les prédécesseurs de Léopards qui sont encore bien présents (et pour cause :rolleyes: ) et qui le resterons encore un petit moment d'où des problèmes de compatibilité.

Donc pour moi, le GC d'Obj-C va rester un choix (tout comme en langage D il me semble) et à ce titre je trouve que c'est une très bonne chose.

c'est juste pour quelq'un qui donne comme exemple le cplusplus, et qu'on lui propose un language objet avec des retain et des release (alloc free) cela peut paraitre assez bizarre et assez chiant,
Et les new/delete du C++ sont quoi si ce n'est des équivalents aux new/release d'Obj-C? La notion d'autorelease/retain est juste un complément dont la seul alternative en C++ est l'implémentation de callbacks ou de smart pointers (qui a dit chiant?:D ) car le C++ offre par défaut une gestion entièrement manuelle.
 
Y a pas de mal. ;)
C'est le terme "obsolète" qui m'a fait réagir car le raccourci était un peu rapide. Il y a deux raisons majeures à cela:
- Les GC sont loin d'être la solution miracle en terme de performances/gestion des ressources.
- C'était faire un peu vite l'impasse sur les prédécesseurs de Léopards qui sont encore bien présents (et pour cause :rolleyes: ) et qui le resterons encore un petit moment d'où des problèmes de compatibilité.

Donc pour moi, le GC d'Obj-C va rester un choix (tout comme en langage D il me semble) et à ce titre je trouve que c'est une très bonne chose.


Et les new/delete du C++ sont quoi si ce n'est des équivalents aux new/release d'Obj-C? La notion d'autorelease/retain est juste un complément dont la seul alternative en C++ est l'implémentation de callbacks ou de smart pointers (qui a dit chiant?:D ) car le C++ offre par défaut une gestion entièrement manuelle.

oui avec boost , qui a dit smart :D
oui le garbage collector mechanisme est théoriquement le même
 
@Mala:
Bon, je viens de faire une première fonction en Objective-C qui fait quelque chose.

Voilà le code:
Bloc de code:
#import <Foundation/Foundation.h>
#define SAFE_RELEASE(p)   { if (p) { [p release]; } }
int main(int argc, char** argv)
{
 NSAutoreleasePool*  pool=[NSAutoreleasePool new];
 NSSttring*  fileName="FF01"; // il faut un arobas apr&#232;s le = pour que &#231;a compile
 NSData*    fileContent=[NSData dataWithContentsOfFile: fileName];
 unsigned char*   bytes=(unsigned char*) [fileContent bytes];
 int    nCol=0, i=-1;
 for (i=0; i<[fileContent length]; i++, nCol++)
 {
  if (nCol > 16)
  {
   nCol=0;
   printf("\n");
  }
  printf("&#37;02x ", bytes[i]);
 }
 
 printf("\n");
 [fileName retain];
 [fileContent retain];
 SAFE_RELEASE(pool);
 return 0;
}

Bon, l&#224;, j'ai tout mis dans le main ;)

Il affiche en hexa le contenu du fichier que je charge et c'est bon.
Pour bien faire, faudrait que je trappe les exceptions lors de l'ouverture du fichier et l'allocation des pointeurs, mais c'est pour l'exemple ;)

Est-ce bien du Cocoa ce que j'ai fais? En tout cas, je commence &#224; piger l'Objective-C. Le tout est de connaitre les classes.

N'y a-t-il pas un moyen plus "Cocoa" ou plus Apple-Like que ce que j'ai fais pour acc&#233;der aux donn&#233;es?

Pour mon code, je dois analyser octet par octet le contenu du fichier qui contient en fait les descripteurs de niveaux (taille du niveau, indexes de tiles, table d'actions etc.) , afin de recr&#233;er en m&#233;moire le niveau dans une structure que j'&#233;crirais en Objective-C.

fred.
 
Il affiche en hexa le contenu du fichier que je charge et c'est bon.
Ok, donc pas de souci de plateforme comme je l''&#233;voquais.

Pour bien faire, faudrait que je trappe les exceptions lors de l'ouverture du fichier et l'allocation des pointeurs, mais c'est pour l'exemple ;)
Cocoa fait un usage assez restreint des exceptions (d'ailleurs la gestion des exceptions Objective-C n'est pas active par d&#233;faut il me semble lorsqu'on cr&#233;er un projet xcode). Ici, il te suffit de tester "fileContent" qui est mit &#224; nil par dataWithContentsOfFile si la lecture se passe mal (tape "dataWithContentsOfFile" dans AppKiDo, tu vas voir il va t'emmener directement dessus...
Return Value
A data object by reading every byte from the file specified by path.
Returns nil if the data object could not be created.

Est-ce bien du Cocoa ce que j'ai fais? En tout cas, je commence &#224; piger l'Objective-C. Le tout est de connaitre les classes.
Ton code marche mais tu as des fuites.

Quand tu fais &#224; la fin de ton code:
Bloc de code:
[fileName retain];
[fileContent retain];
Tu te r&#233;serves la gestion m&#233;moire de ces deux objets. Donc lorsque tu fais le release sur ton pool juste apr&#232;s, il ne s'occupe pas de ces deux lascars. Soit tu supprimes les "retain", soit-tu fais en "release" dessus par la suite (mais dans le cas pr&#233;sent &#231;a n'a pas grand int&#233;r&#234;t. prends le temps de bien relire ce que je t'ai expliqu&#233; dans me post pr&#233;c&#233;dents. Sinon, tu peux aussi jeter un oeil &#224; cet article de Renaud sur la gestion m&#233;moire et qui est tr&#232;s bien fait: Gestion de la m&#233;moire en Objective-C

N'y a-t-il pas un moyen plus "Cocoa" ou plus Apple-Like que ce que j'ai fais pour acc&#233;der aux donn&#233;es?

Pour mon code, je dois analyser octet par octet le contenu du fichier qui contient en fait les descripteurs de niveaux (taille du niveau, indexes de tiles, table d'actions etc.) , afin de recr&#233;er en m&#233;moire le niveau dans une structure que j'&#233;crirais en Objective-C.
A premi&#232;re vue, je dirais que c'est d&#233;j&#224; pas mal. Un m&#233;lange d'Obj-C pour le fonctionnel et de C pure pour les performances en ce qui concerne l'acc&#232;s au buffer.

Eventuellement, ce que je ferais perso:
- ajouter une variable genre "int length = [fileContent length]" et l'utiliser dans la boucle. Cela &#233;vite de passer son temps &#224; rappeler une m&#233;thode dont le retour ne change jamais. Le c&#244;t&#233; dynamique d'Obj-C a aussi une contrepartie-> la lenteur des appels de m&#233;thode du fait de l'aiguillage &#224; la vol&#233;e.
- remplacer les printf par des NSLog(). La syntaxe d'utilisation est la m&#234;me (aux caract&#232;res @ pr&#232;s pour indiquer une cha&#238;ne Obj-C mais tu peux en plus tracer des objets Obj-C avec) et &#231;a trace en plus dans le fichier de log.
ex:
Bloc de code:
NSLog(@"&#37;@",[fileContent description])
La m&#233;thode description nous permet ici de demander &#224; l'objet de se d&#233;tailler sous forme d'une cha&#238;ne NSString.

Dans ton cas pour faire exactement la m&#234;me chose que toi, on fait par exemple:
Bloc de code:
NSLog(@"%02x ", bytes[i]);
 
Salut,

NSLog pour la sortie n'est pas terrible. En effet, il met tout en bloc et met des timestamps lors que j'utilise le formatage %02x.

J'imagine qu'il y a moyen d'avoir l'équivalent du printf en Cocoa.

Sinon, j'ai vu le pourquoi des fuites. "Retain" fait de la rétention de données mémoire, comme son nom l'indique et le pool vide ce qui lui a été donné lors du release si j'ai bien compris.

Maintenant, que j'ai pigé l'Objective-C, reste plus qu'à comperendre l'arcjitecture Cocoa et de prendre mes repères. :)

Fred.
 
En effet, il met tout en bloc et met des timestamps lors que j'utilise le formatage %02x.
En effet, je n'avais pas pensé que le timestamps pouvait te gêner. A ma connaissance, il n'y a pas d'équivalent au printf simple en Obj-C. Dans le contexte de Cocoa, les retours utilisateurs sont avant tout graphiques. Lorsqu'on fait des traces texte c'est qu'on veut en garder une trace (d'où la datation des logs).

Mais tu peux néanmoins très bien mélanger les genres pour tes besoins. Voici trois exemples d'équivalences (au timestamps près)...
Bloc de code:
   // En C simple
    char buffer [50];
    int n, a=5, b=3;
    n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
    printf ("[%s] is a %d char long string\n",buffer,n);
    
    // En Objective-C
    NSString *myString = [NSString stringWithFormat:@"%d plus %d is %d", a, b, a+b];
    NSLog(@"[%@] is a %d char long string\n",myString);
    
    // En mélangeant C et Objective-C
    NSString *myString2 = [NSString stringWithFormat:@"%d plus %d is %d", a, b, a+b];
    printf ("[%s] is a %d char long string\n",[myString2 cString],[myString2 length]);