2010-10-17 3 views
7

J'ai une requête simple que je voudrais éclaircir par quelqu'un ... Est-ce une mauvaise pratique de se retenir?Mauvaise pratique à retenir soi-même?

J'ai un objet de demande de serveur que je voudrais faire. Je voudrais pouvoir l'utiliser de la façon suivante:

ARequest *request = [ARequest request: someParam]; 
request.delegate = self; 
[request begin]; 

Pour que l'objet ne pas Autodestruction dès que la piscine autorelease est drainée, je pense que je dois appeler un conserver dans son méthode init, puis une version une fois que la réponse du serveur a été reçue, traitée et remise à son délégué.

Cependant, quelque chose soulève une cloche d'avertissement dans ma tête avec cette approche. De meilleures façons de le faire?

Répondre

6

Il n'y a rien de mal à conserver self, tant que vous le relâchez à un point bien défini conformément au protocole normal de gestion de la mémoire. Si un objet a besoin d'exister jusqu'à ce que certaines conditions soient remplies, il doit en assumer la responsabilité, de la même manière que pour tout autre objet dont il a besoin pour continuer à exister.

L'introduction d'objets de gestion par ailleurs étrangers ou la mise en cause de la responsabilité sur le propriétaire de l'objet pour des raisons superstitieuses serait le véritable anti-pattern ici.

(L'approche équivalente dans le code ramasse-miettes serait pour l'objet lui-même exclure de la collecte des ordures alors que les résultats sont en attente, ou de la racine à travers une collection de quelque sorte si vous ne pas aimer cette idée.)

1

Le moyen le plus simple de le faire serait de créer un iVar pour votre requête, de conserver la requête lorsque vous la démarrez et de la libérer lorsque la dernière méthode déléguée est appelée.

Est-ce que ARequest est une classe que vous avez créée? Crée-t-il un nouveau thread pour soumettre la requête de manière asynchrone?

+0

Oui, ARequest est fondamentalement une classe qui crée un NSURLConnection pour soumettre une requête de manière asynchrone. Je pourrais utiliser un ivar, mais je pourrais avoir quelques requêtes envoyées en même temps, donc je devrais alors maintenir une collection de requêtes de quelque sorte. Apple semble utiliser un modèle qui ne nécessite pas la maintenance de ce genre (SKProductsRequest par exemple). – Tricky

0

J'ai déjà fait la même chose que vous. J'ai écrit une méthode de catégorie sur NSString pour l'envoyer à un serveur, qui l'imprimera. Dans la méthode de catégorie, j'ai dû appeler [self retain], de sorte que les méthodes de rappel puissent être une méthode NSString-Categroy.
Je me sentais si mal à ce sujet, que j'ai tout réécrit pour utiliser un Singleton, qui est accessible par la méthode de catégorie. Ainsi, le Singleton conservera la chaîne aussi longtemps que nécessaire.

+0

Oui, c'est la chose ... Il se sent 'mauvais' pour une raison quelconque, mais je me demande si c'est vraiment? Apple gère cela d'une manière ou d'une autre dans SKProductsRequest par exemple, mais est-ce via un [self retain] ou maintient-il une collection de requêtes en attente quelque part? – Tricky

2

Ce n'est pas du jamais vu, mais c'est plutôt rare. La principale façon dont je l'ai vu utilisé (et utilisé moi-même) est quand vous avez affaire à une sorte d'objet semi-synchrone (par semi-synchrone, je veux dire qu'il ne bloque pas le fil principal, mais il ne le fait pas exécuter sur un fil d'arrière-plan, un NSURLConnection correspondrait à cette facture). Par exemple, j'ai écrit une sous-classe de NSWindowController qui était spécifiquement pour afficher une fenêtre en tant que feuille et pour appeler certains rappels de délégué. Fondamentalement, vous auriez un nouveau contrôleur de feuille et invoquer beginSheetForWindow:. Cela exécuterait la feuille de façon semi-synchrone, puis invoquer un rappel approprié lorsque la feuille a été rejetée. Étant donné que l'objet invoquant ne possède pas nécessairement la feuille (pensez à une version Mac d'un contrôleur de vue modale sur iOS), le contrôleur de feuille exécute [self retain] immédiatement avant l'affichage de la feuille et [self release] immédiatement après le nettoyage. et invoquer des rappels. Le but derrière ceci était de s'assurer que l'objet contrôleur resterait jusqu'à ce que la feuille ait été faite.

Comme je l'ai dit, il est très rare de trouver une situation où vous voudriez [self retain], mais ce n'est pas impossible. (La feuille, IIRC, a été retenue par le runloop. Cependant, en règle générale, si vous pensez que vous avez besoin de [self retain], vous pouvez réfléchir à nouveau.

Questions connexes