Alors commençons par le commencement. Objective-C et cocoa en général fonctionne avec des "autorelease pool" qui permettent de s'affranchir dans certaines conditions de la gestion mémoire. Chaque thread (dans ton cas ton main est le thread principal) doit disposer dau moins un pool qui va stocker et gérer les objets autorelease.
Là tu vas me dire:"mais je fais tout moi même".
Oui mais non, en appelant par exemple dataWithContentsOfFile tu utilises ce que l'on appel un constructeur de commodité qui te retourne un objet alloué en mode autorelease (c'est comme ça que fonctionne la plupart des constructeurs de commodité

.
Du coup le programme pense qu'il y a une perte mémoire car tu as créé un objet qui n'est associé à aucun pool.
Donc pour résoudre ce problème:
Ajoute en tout début du main:
Bloc de code:
NSAutoreleasePool *pool = [NSAutoreleasePool new];
Et à la fin du code en toute dernière ligne:
Et là ça plante encore. Pourquoi?
Et bien tout simplement parce que ta macro SAFE_RELEASE n'a pas de raison d'être sur des objets qui sont autorelease. Au contraire, tu vas libérer les objets et derrière ton pool va essayer de faire de même et patatra.
Deux solutions:
- Soit tu supprimes l'appel à ta macro.
- Soit en tant que programmeur consciencieux tu ne l'entend pas de cette oreille et tu veux avoir tout pouvoir sur les objets que tu alloues dans ton code. Dans ce second cas, tu ajouteras le code suivant après la création de tes objets:
Bloc de code:
[fileName retain];
[fileContent retain];
Et là pour faire simple, tu indiques à l'autorelease pool qu'il est bien mignon mais que jusqu'à preuve du contraire c'est toi le boss et que les objets tu te les libères toi même.
Toujours très perspicace, tu me rétorques alors : "Quel est alors l'intérêt des objets gérés en autorelease???"
Et bien imagines un objet dont l'utilisation est partagées par plusieurs autres objets (ex: une ressource genre une image jpeg). Lequel des objets à le droit de supprimer l'espace mémoire alloué par l'objet image s'il n'en a plus besoin? Dur dilemme. :hein: Et là le mode autorelease prend tout son intérêt. :zen: On passe l'objet image en tant qu'objet autorelease aux autres objets. Chaque objet qui veut conserver l'image fait alors un retain dessus et cela incrémente un compteur associé à notre ressource. Une fois qu'un objet ne veux plus garder la ressource, il fait un release sur l'objet image. Lorsque le compteur arrive a zéro, plus personne n'utilise l'image alors l'objet se libère.