Différences entre fort et faible dans l'Objectif-C

308

Je suis nouveau à Obj-C, donc ma première question est:

Quelles sont les différences entre stronget weakdans les @propertydéclarations de pointeurs vers des objets?

Et qu'est-ce que cela nonatomicsignifie également?

Mark Pegasov
la source
19
en fait, c'est une bonne question, parfois, nous avons oublié comment le concept de base des préférences fortes / faibles et atomiques / nonatomiques .... :) Merci de nous le rappeler ...
andikurnia
10
@JackyBoy Ce qui est drôle, c'est que la simple recherche proposée sur google m'a conduit ici lol. #circularreference
Jason Renaldo
10
J'ai tendance à ne pas faire confiance à la plupart des réponses sur Google, mais je me réfère toujours à SO pour des réponses intelligentes
JeffK

Réponses:

642

Une référence forte (que vous utiliserez dans la plupart des cas) signifie que vous souhaitez "posséder" l'objet auquel vous faites référence avec cette propriété / variable. Le compilateur veillera à ce que tout objet que vous affectez à cette propriété ne soit pas détruit tant que vous le pointez avec une référence forte. Une fois que vous avez défini la propriété surnil que l'objet sera détruit (sauf si un ou plusieurs autres objets y contiennent également une référence forte).

En revanche, avec une référence faible, vous signifiez que vous ne voulez pas avoir de contrôle sur la durée de vie de l'objet. L'objet auquel vous faites référence faiblement ne vit que parce qu'au moins un autre objet en possède une forte référence. Une fois que ce n'est plus le cas, l'objet est détruit et votre propriété faible sera automatiquement réglée sur nil. Les cas d'utilisation les plus fréquents des références faibles dans iOS sont:

  1. déléguer des propriétés, souvent mal référencées pour éviter les cycles de rétention, et

  2. sous-vues / contrôles de la vue principale d'un contrôleur de vue, car ces vues sont déjà fortement détenues par la vue principale.

atomic vs nonatomic fait référence à la sécurité des threads des méthodes getter et setter que le compilateur synthétise pour la propriété. atomic (la valeur par défaut) indique au compilateur de rendre les méthodes d'accesseur thread-safe (en ajoutant un verrou avant d'accéder à un ivar) et nonatomic fait le contraire. L'avantage du nonatomique est des performances légèrement supérieures. Sur iOS, Apple utilise non atomique pour presque toutes leurs propriétés, donc le conseil général est que vous fassiez de même.

Ole Begemann
la source
28
@Bourne: Cela dépend de ce que vous entendez par sécurité des threads. atomicgarantit que le propriété peut être lue et écrite en toute sécurité à partir de plusieurs threads en même temps. Cela ne signifie pas qu'un objet dont les propriétés sont toutes atomicest automatiquement thread-safe.
Ole Begemann
3
Grands détails. Je pense que je ne l'ai pas vraiment compris jusqu'à présent. Je vous remercie.
ahmedalkaff
1
Selon la documentation d'Apple, atomic et nonatomic devraient être synonymes de sécurité des threads. developer.apple.com/library/ios/documentation/cocoa/conceptual/…
Murtaza Khursheed Hussain
5
"Remarque: l'atomicité des propriétés n'est pas synonyme de sécurité des threads d'un objet." developer.apple.com/library/ios/documentation/cocoa/conceptual/…
GS
pourquoi ne supprimons-nous pas simplement l'instance quand nous ne voulons pas? Pourquoi ne pouvons-nous pas simplement retirer l'air du ballon ou le détruire lorsque nous ne voulons pas, pourquoi devons-nous nous soucier des cordes attachées? Nous avons juste besoin de données.
Ashish Pisey
707

Il peut être utile de réfléchir à des références fortes et faibles en termes de ballons.

Un ballon ne s'envolera pas tant qu’au moins une personne s’accroche à une ficelle qui lui est attachée. Le nombre de personnes détenant des chaînes est le nombre de retenues. Lorsque personne ne tient à une corde, le ballon s'envole (dealloc). Beaucoup de gens peuvent avoir des cordes sur ce même ballon. Vous pouvez obtenir / définir des propriétés et des méthodes d'appel sur l'objet référencé avec des références fortes et faibles.

Une référence forte, c'est comme tenir une chaîne à ce ballon. Tant que vous tenez une corde attachée au ballon, il ne s'envolera pas.

Une référence faible, c'est comme regarder le ballon. Vous pouvez le voir, accéder à ses propriétés, appeler ses méthodes, mais vous n'avez pas de chaîne pour ce ballon. Si tout le monde se cramponne à la ficelle, le ballon s'envole et vous ne pouvez plus y accéder.

MJN
la source
68
+2 (si seulement je pouvais). Sérieusement, une explication vraiment créative!
Con Antonakos
25
Après 1 an et demi de développement iOS, je pense que je viens de comprendre clairement ce que je veux dire stronget en weakfait.
Isuru
17
@ X.Li Retain cycle, c'est comme si vous aviez 2 cordes pour le ballon, l'une d'entre elles vous appartient (donc vous possédez ce ballon), l'autre appartient au ballon (donc ce ballon vous appartient). Puisque vous n'avez accès qu'à votre chaîne, comment laissez-vous le ballon partir si le ballon ne veut pas partir? Il est donc préférable que vous possédiez le ballon (fort) alors que le ballon ne vous appartient pas (faible). Lorsque vous voulez le laisser partir, coupez simplement la chaîne :)
snakeninny
5
Lisez son profil, c'est un instructeur iOS. Explication très créative !! Chapeau :)
Hemang
3
Atomique vs non atomique, je pense, peut être décrit comme une salle de toilettes publiques avec plusieurs portes, avec une toilette au centre. Une fois que quelqu'un entre dans les toilettes par une porte, il pourrait aussi bien verrouiller toutes les autres portes dans les toilettes s'il ne veut pas vivre un moment de maladresse. Lol. Merci d'avoir lu cette analogie absurde.
Chen Li Yong
24

fort : lui attribue la valeur entrante, il conservera la valeur entrante et libérera la valeur existante de la variable d'instance

faible : lui attribuera la valeur entrante sans la conserver.

La différence fondamentale est donc le maintien de la nouvelle variable. En général, vous voulez le conserver, mais il y a des situations où vous ne voulez pas l'avoir sinon vous obtiendrez un cycle de conservation et ne pourrez pas libérer la mémoire des objets. Par exemple. obj1 conserve obj2 et obj2 conserve obj1. Pour résoudre ce genre de situation, vous utilisez des références faibles.

Pfitz
la source
12

Une réponse factice: -

Je pense que l'explication est donnée dans la réponse ci-dessus, donc je vais juste vous dire où utiliser STRONGet où utiliser WEAK:

Utilisation de Weak: - 1. Délégués 2. Points de vente 3. Sous-vues 4. Commandes, etc.

Utilisation de Strong: - Restant partout qui n'est pas inclus dans WEAK.

shubham mishra
la source
2
Et qu'est-ce que etc contient: P
Rajneesh071
3
webView, mapView, etc
shubham mishra
4
en fait la plupart des sous-vues que nous glissons et
déposons
8

forts et faibles , ces mots clés tournent autour de la propriété d'objets dans Objective-C

Qu'est-ce que la propriété d'objet?

Les variables de pointeur impliquent la propriété des objets vers lesquels elles pointent.

  • Lorsqu'une méthode (ou fonction) a une variable locale qui pointe vers un objet, cette variable est réputée posséder l'objet pointé.
  • Lorsqu'un objet a une variable d'instance qui pointe vers un autre objet, l'objet avec le pointeur est réputé posséder l'objet pointé.

Chaque fois qu'une variable de pointeur pointe vers un objet, cet objet a un propriétaire et restera en vie. Ceci est connu comme une référence forte .

Une variable ne peut éventuellement pas s'approprier un objet vers lequel elle pointe. Une variable qui ne s'approprie pas un objet est connue comme une référence faible .

Découvrez ici une explication détaillée Démystifier @property et ses attributs

Vinay Jain
la source
6

Ici, la documentation Apple a expliqué la différence entre une propriété faible et une propriété forte à l'aide de divers exemples:

https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3

Ici, dans ce blog, l'auteur a rassemblé toutes les propriétés au même endroit. Cela aidera à comparer les caractéristiques des propriétés:

http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html

subhash kumar singh
la source
6

fort est la valeur par défaut. Un objet reste «vivant» tant qu'il y a un pointeur fort vers lui.

faible spécifie une référence qui ne maintient pas vivant l'objet référencé. Une référence faible est définie sur zéro lorsqu'il n'y a pas de références fortes à l'objet.

Ankit Vyas
la source
2

Pour comprendre les références fortes et faibles, considérons l'exemple ci-dessous, supposons que nous ayons une méthode nommée displayLocalVariable.

 -(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
  }

Dans la méthode ci-dessus, la portée de la variable myView est limitée à la méthode displayLocalVariable, une fois que la méthode est terminée, la variable myView qui contient l'objet UIView sera désallouée de la mémoire.

Maintenant, que faire si nous voulons conserver la variable myView tout au long du cycle de vie de notre contrôleur de vue. Pour cela, nous pouvons créer la propriété nommée usernameView qui aura une référence forte à la variable myView (voir @property(nonatomic,strong) UIView* usernameView;et self.usernameView = myView;dans le code ci-dessous), comme ci-dessous,

@interface LoginViewController ()

@property(nonatomic,strong) UIView* usernameView;
@property(nonatomic,weak) UIView* dummyNameView;

- (void)displayLocalVariable;

@end

@implementation LoginViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

-(void)viewWillAppear:(BOOL)animated
{
     [self displayLocalVariable];
}

- (void)displayLocalVariable
{
   UIView* myView = [[UIView alloc] init];
   NSLog(@"myView tag is = %ld", myView.tag);
   self.usernameView = myView;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


@end

Maintenant, dans le code ci-dessus, vous pouvez voir que myView a été affecté à self.usernameView et self.usernameView a une référence forte (comme nous l'avons déclaré dans l'interface en utilisant @property) à myView. Par conséquent, myView ne sera pas désalloué de la mémoire tant que self.usernameView ne sera pas actif.

  • Référence faible

Envisagez maintenant d'attribuer myName à dummyNameView qui est une référence faible, self.dummyNameView = myView;contrairement à la référence forte, faible ne conservera le myView que jusqu'à ce qu'il y ait une référence forte à myView. Voir le code ci-dessous pour comprendre la référence faible,

-(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
     self.dummyNameView = myView;
  }

Dans le code ci-dessus, il y a une référence faible à myView (c'est-à-dire que self.dummyNameView a une référence faible à myView) mais il n'y a pas de référence forte à myView, donc self.dummyNameView ne pourra pas contenir la valeur myView.

Maintenant, considérez à nouveau le code ci-dessous,

-(void)displayLocalVariable
      {
         UIView* myView = [[UIView alloc] init];
         NSLog(@"myView tag is = %ld", myView.tag);
         self.usernameView = myView;
         self.dummyNameView = myView;
      } 

Dans le code ci-dessus, self.usernameView a une référence forte à myView, donc self.dummyNameView aura désormais une valeur de myView même après la fin de la méthode, car myView a une référence Strong associée.

Maintenant, chaque fois que nous faisons une référence forte à une variable, son nombre de rétentions est augmenté d'une unité et la variable ne sera pas désallouée tant que son nombre de rétentions n'aura pas atteint 0.

J'espère que cela t'aides.

Mahadev Mandale
la source
2019-07-25 12: 33: 15.479002 + 0530 StrongAndWeak [6329: 245483] Mon nom est = ABC 2019-07-25 12: 33: 15.479226 + 0530 StrongAndWeak [6329: 245483] Mon nom est pour strong = ABC 2019- 07-25 12: 33: 15.479418 + 0530 StrongAndWeak [6329: 245483] Mon nom est pour faible = ABC dans ce que vous avez dit que la propriété faible n'a pas la valeur de myname .Mais je reçois la valeur de myname comme ABC pour les deux références .. ..? pouvez-vous donner une réponse plus claire .... Merci d'avance
Madhu_Nani
@Raviteja_DevObal ARC ne promet pas de le faire immédiatement (c'est-à-dire désallouer la chaîne @ "ABC"), mais il sera certainement désalloué plus tard ...
Mahadev Mandale
@Raviteja_DevObal As Expliquez ici les chaînes sont un mauvais exemple pour cela. J'ai mis à jour ma réponse avec l'objet UIView, j'espère que cela aide.
Mahadev Mandale
1

Strong : Fondamentalement utilisé avec les propriétés, nous avons utilisé pour obtenir ou envoyer des données de / vers d'autres classes. Faible : généralement toutes les prises, les connexions sont de type faible à partir de l'interface.

Non anatomique : ce type de propriétés est utilisé dans des conditions où nous ne voulons pas partager notre sortie ou notre objet dans différents threads simultanés. En d'autres termes, l'instance Nonatomic fait que nos propriétés traitent avec un thread à la fois. J'espère que cela vous sera utile.

Joga singh
la source