NSString propriété: la copie ou de la conserver?
Disons que j'ai une classe appelée SomeClass
avec un string
nom de la propriété:
@interface SomeClass : NSObject
{
NSString* name;
}
@property (nonatomic, retain) NSString* name;
@end
Je comprends que nom peut être attribué à une NSMutableString
dans ce cas, il peut conduire à des errants comportement.
- Pour cordes en général, est-il toujours une bonne idée d'utiliser le
copy
attribut au lieu deretain
? - Est un "copié" bien moins efficace qu'une telle "conserver-ed" à la propriété?
- Question de suivi: Doit
name
être publié dansdealloc
ou pas? - Oui il devrait!
Vous devez vous connecter pour publier un commentaire.
Pour les attributs dont le type est une valeur immuable classe qui est conforme à la
NSCopying
protocole, vous avez presque toujours doit précisercopy
dans votre@property
déclaration. La spécification deretain
est presque quelque chose que vous ne voulez jamais dans une telle situation.Voici pourquoi vous voulez le faire:
La valeur actuelle de la
Person.name
propriété sera différente selon que la propriété est déclaréeretain
oucopy
— il sera@"Debajit"
si la propriété est marquéeretain
, mais@"Chris"
si la propriété est marquéecopy
.Car dans presque tous les cas, vous voulez empêcher la mutation d'un objet d'attributs de derrière son dos, vous devez marquer les propriétés représentant
copy
. (Et si vous écrivez le setter vous-même au lieu d'utiliser@synthesize
vous devriez vous rappeler d'utiliser effectivementcopy
au lieu deretain
en elle.)NSMutableString
, sauf en tant que passagère "générateur de chaîne de type" (à partir de laquelle j'ai immédiatement prendre un immuable copie). Je leur préfèrent être discrets types - mais je ne me permets que le fait que la copie est libre de faire retenir si la chaîne d'origine n'est pas mutable atténue la plupart de mes préoccupations.Copie doit être utilisé pour NSString. Si c'est Mutable, alors il est copié. Si c'est non, alors il est juste maintenu. Exactement la sémantique que vous voulez dans une application (laissez le type de faire ce qui est mieux).
NSString
propriété déclarée commecopy
obtiendrezretain
de toute façon (si c'est immuable, bien sûr). Autre exemple, je penseNSNumber
.Oui - en général toujours utiliser la copie de l'attribut.
C'est parce que votre NSString propriété peut être passé un NSString instance ou un NSMutableString instance, et donc on ne peut pas vraiment déterminer si la valeur transmise est immuable ou mutable objet.
Si votre propriété est transférée à un NSString instance, la réponse est "Pas" - la copie n'est pas moins efficace que de les garder.
(Il n'est pas moins efficace car la NSString est assez intelligent pour ne pas effectuer une copie.)
Si votre propriété est passée NSMutableString instance alors la réponse est "Oui" - la copie est moins efficace que de les garder.
(C'est moins efficace, parce que l'une réelle, l'allocation de la mémoire et de la copie doit se produire, mais c'est probablement une chose souhaitable.)
Généralement un "copié" la propriété a le potentiel pour être de moins en moins efficace - cependant grâce à l'utilisation de la
NSCopying
protocole, il est possible de mettre en œuvre une classe qui est "aussi efficace" de la copie est à conserver. NSString instances en sont un exemple.Vous devriez toujours utiliser
copy
lorsque vous ne voulez pas l'état interne de la propriété de changer sans avertissement. Même pour des objets immuables - écrit correctement des objets immuables va gérer la copie de manière efficace (voir la section suivante concernant l'immuabilité etNSCopying
).Il peut y avoir des raisons de performances à
retain
objets, mais il est livré avec une charge de maintenance - vous devez gérer la possibilité de l'état interne de changer à l'extérieur de votre code. Comme ils disent - optimiser dernier.De non - utilisation
copy
. Si votre classe n'est vraiment immuable, alors il est recommandé de mettre en œuvre lesNSCopying
protocole pour faire de votre retour, en classe elle-même quandcopy
est utilisé. Si vous faites cela:copy
.copy
annotation rend votre code plus maintenable - lecopy
annotation indique que vous n'avez vraiment pas besoin de s'inquiéter à propos de cet objet de changement d'état par ailleurs.J'essaie de suivre cette règle simple:
Ne je veux la valeur de l'objet au point dans le temps quand je suis en l'assignant à ma propriété? Utilisation copie.
Ne je veux la objet et je n'aime pas ce que ses valeurs internes sont actuellement ou seront à l'avenir? Utilisation forte (conserver).
Pour illustrer: je veux tenir à la nom "Lisa Miller" (copie) ou je veux le personne Lisa Miller (forte)? Son nom pourrait le changer plus tard pour "Lisa Smith", mais elle sera toujours la même personne.
À travers cet exemple de copie et de conserver ce qui peut être expliqué comme:
si la propriété est de type copie ensuite ,
une nouvelle copie sera créée pour le
[Person name]
chaîne qui contiendra le contenu desomeName
chaîne. Maintenant, toute opération sursomeName
chaîne n'aura aucun effet sur[Person name]
.[Person name]
etsomeName
chaînes différentes qui ont des adresses de mémoire.Mais dans le cas de la conserver,
à la fois la
[Person name]
tiendra la même adresse mémoire de chaîne abc, juste le conserver compter de la chaîne abc sera incrémentée de 1.De sorte que tout changement dans la chaîne abc, sera reflété dans
[Person name]
chaîne.Sûrement mettre "copier" sur une déclaration de propriété vole dans le visage de l'utilisation d'un objet-orienté environnement où les objets sur le tas sont passés par référence - l'un des avantages que vous obtenez ici est que, lors de la modification d'un objet, toutes les références à cet objet voir les dernières modifications. Beaucoup de langues d'approvisionnement " ref " ou les mots clés similaires pour permettre à des types de valeur (c'est à dire des structures sur la pile) de bénéficier de la même comportement. Personnellement, je préfère utiliser la copie avec parcimonie, et si je sentais que la valeur d'une propriété doit être protégé contre les modifications apportées à l'objet qu'il a été attribué à partir, j'ai pu appeler cet objet de la méthode de copie lors de l'affectation, par exemple:
Bien sûr, lors de la conception de l'objet qui contient la propriété, que vous permettra de savoir si les avantages de la conception d'un modèle où les affectations de prendre des copies - Cocoawithlove.com a ceci à dire:
", Vous devez utiliser une copie de l'accesseur lorsque le setter paramètre peut être mutable mais vous ne pouvez pas l'état interne d'une propriété de changer sans avertissement" - de sorte que le jugement quant à savoir si vous pouvez vous tenir sur la valeur à modifier de façon inattendue est tout votre propre. Imaginez ce scénario:
Dans ce cas, sans l'aide de copier, notre contact de l'objet prend la nouvelle valeur automatiquement; si nous ne les utiliser, cependant, nous devrions avoir à manuellement, assurez-vous que les changements ont été détectés et synchronisés. Dans ce cas, de conserver la sémantique pourrait être souhaitable, dans l'autre copie pourrait être plus approprié.
Vous devez utiliser copie tout le temps de déclarer NSString propriété
Vous devez lire ces pour plus d'informations sur s'il retourne immuable de la chaîne (dans le cas mutable chaîne a été passé) ou renvoie une retenue de la chaîne (dans le cas immuable de la chaîne a été passé)
NSCopying Protocole De Référence
Des Objets De Valeur
Depuis le nom est un (immuable)
NSString
, de la copie ou de la conserver, ne fait aucune différence si vous définissez une autreNSString
de nom. En un mot, la copie se comporte comme conserver, en augmentant le nombre de références par un. Je pense que c'est une optimisation automatique pour immuable classes, car ils sont immuables et pas besoin d'être cloné. Mais quand unNSMutalbeString
mstr
est défini sur le nom, le contenu demstr
sera copié par souci d'exactitude.Si la chaîne est très grande, puis copiez affectera les performances et les deux copies de la grande chaîne de l'utilisation de la mémoire.