Schwache und starke Eigenschaftensetzerattribute in Objective-C

94

Was ist der Unterschied zwischen schwachen und starken Eigenschaftensetzerattributen in Objective-C?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Was ist die Auswirkung und der Nutzen?

Ich habe gehört, dass schwach unter iOS 4 nicht verfügbar ist und wir Assign verwenden müssen.

Ist schwach ähnlich zuzuweisen?

kkurni
quelle

Antworten:

102

Sie haben entweder ARC für eine bestimmte Datei aktiviert oder deaktiviert. Wenn es aktiviert ist, können Sie nicht retain release autoreleaseetc ... verwenden. Stattdessen verwenden Sie strong weakfür Eigenschaften oder __strong __weak für Variablen (standardmäßig __strong). Stark ist das Äquivalent zum Beibehalten, ARC verwaltet die Veröffentlichung jedoch für Sie.

Das einzige Mal, wenn Sie schwach verwenden möchten, ist, wenn Sie Aufbewahrungszyklen vermeiden möchten (z. B. behält der Elternteil das Kind und das Kind behält den Elternteil, sodass keiner jemals freigegeben wird).

Der Teil "gebührenfreie Überbrückung" (Casting von NSbis CF) ist etwas schwierig. Sie haben noch manuell verwalten CFRelease()und CFRetain()für CF - Objekte. Wenn Sie sie wieder in NS-Objekte konvertieren, müssen Sie dem Compiler die Anzahl der Aufbewahrungen mitteilen, damit er weiß, was Sie getan haben.

Es ist alles hier .

Robert
quelle
119

Hier finden Sie Informationen zu den Eigenschaften von Variablen

  1. atomar // Standard
  2. nichtatomar
  3. strong = beibehalten // Standard
  4. schwach
  5. behalten
  6. // Standard zuweisen
  7. unsafe_unretained
  8. Kopieren
  9. schreibgeschützt
  10. readwrite // default

Im Folgenden finden Sie den detaillierten Artikel-Link, über den Sie alle oben genannten Attribute finden, die Ihnen trotzig helfen werden. Vielen Dank an alle, die hier die besten Antworten geben !!

Variable Eigenschaftsattribute oder Modifikatoren in iOS

01. stark (iOS4 = beibehalten) - es heißt " Behalte dies auf dem Haufen, bis ich nicht mehr darauf zeige" - mit anderen Worten "Ich bin der Besitzer, du kannst dies nicht freigeben, bevor du gut mit dem gleichen Ziel wie" Behalten "zielst "- Sie verwenden strong nur, wenn Sie das Objekt behalten müssen. - Standardmäßig sind alle Instanzvariablen und lokalen Variablen starke Zeiger. - Wir verwenden im Allgemeinen strong für UIViewController (die Eltern des UI-Elements). - strong wird mit ARC verwendet und hilft Ihnen im Grunde, indem Sie sich nicht um die Anzahl der Objekte kümmern müssen. ARC gibt es automatisch für Sie frei, wenn Sie damit fertig sind. Wenn Sie das Schlüsselwort strong verwenden, bedeutet dies, dass Sie das Objekt besitzen.

Beispiel:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. schwach (iOS4 = unsafe_unretained) - es heißt " Behalte dies, solange jemand anderes stark darauf hinweist" - dasselbe wie Zuweisen, kein Zurückhalten oder Freigeben - Eine "schwache" Referenz ist eine Referenz, die du nicht behältst. - Wir verwenden im Allgemeinen schwach für IBOutlets (UIViewController's Childs). Dies funktioniert, weil das untergeordnete Objekt nur so lange existieren muss, wie das übergeordnete Objekt. - Eine schwache Referenz ist eine Referenz, die das referenzierte Objekt nicht vor der Sammlung durch einen Garbage Collector schützt. - Schwach ist im Wesentlichen zuzuweisen, eine nicht zurückgehaltene Eigenschaft. Außer wenn das Objekt freigegeben wird, wird der schwache Zeiger automatisch auf Null gesetzt

Beispiel:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

Erklären Sie : Danke an BJ Homer

Stellen Sie sich vor, unser Objekt ist ein Hund und der Hund möchte weglaufen (freigegeben werden). Starke Zeiger sind wie eine Leine am Hund. Solange Sie die Leine am Hund befestigt haben, rennt der Hund nicht weg. Wenn fünf Personen ihre Leine an einem Hund befestigen (fünf starke Zeiger auf ein Objekt), rennt der Hund nicht weg, bis alle fünf Leinen gelöst sind. Schwache Zeiger hingegen sind wie kleine Kinder, die auf den Hund zeigen und sagen: "Schau! Ein Hund!" Solange der Hund noch an der Leine ist, können die kleinen Kinder den Hund noch sehen und sie werden immer noch darauf zeigen. Sobald jedoch alle Leinen gelöst sind, rennt der Hund weg, egal wie viele kleine Kinder darauf zeigen. Sobald der letzte starke Zeiger (Leine) nicht mehr auf ein Objekt zeigt, wird die Zuordnung des Objekts aufgehoben und alle schwachen Zeiger werden auf Null gesetzt. Wann verwenden wir schwach? Das einzige Mal, wenn Sie schwach verwenden möchten, ist, wenn Sie Aufbewahrungszyklen vermeiden möchten (z. B. behält der Elternteil das Kind und das Kind behält den Elternteil, sodass keiner jemals freigegeben wird).

swiftBoy
quelle
1
In der ersten Liste bin ich mir nicht sicher, was Sie unter "Standard" verstehen. Sie haben beide strong=retainund assignals Standardeinstellungen gekennzeichnet, aber es kann nicht beides sein.
Slipp D. Thompson
27
Genossen den Hund an der Leine Vergleich. Erklärt es ziemlich gut.
Jarrett Barnett
1
Gute Erklärung, obwohl iOS keine Speicherbereinigung verwendet. ARC! = Garbage Collection (!), Dies sind verschiedene Technologien.
MorbZ
1
schwach und unsicher_unretained sind unterschiedlich (der erste verwendet null schwache Referenzen, während der letztere
hockt
1
Ich lerne nur iOS, aber es scheint, dass Sie das weakund strongin Ihren Beispielen verlegt haben. Wäre es nicht sinnvoller, wenn ein Elternteil strongVerweise auf seine Kinder hat (als die myButtonEigenschaft der UIViewControllerKlasse, die Sie gezeigt haben weak) und dass die Kinder weakVerweise auf ihre Eltern behalten (wie die viewControllerEigenschaft einer Kinderklasse, die Sie ' ve stattdessen auf strong) gesetzt. Wenn er zum Beispiel Matt Neuburgs liest, iOS 7 Programming Fundamentalszeigt er, dass eine Klasse, die ihren Delegierten als Eigentum deklariert, ihn "schwach" hält, das scheint fair zu sein.
Bogdan Alexandru
2

So rufen Sie die Teile der von Robert referenzierten Dokumente auf, die Ihre letzten beiden Fragen explizit beantworten:

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

Dies wird als schwache Nullreferenz bezeichnet. Mit __unsafe_unretained können Sie schwache Referenzen erstellen, die schwache Referenzen nicht auf Null setzen. Wie der Name schon sagt, wird dies im Allgemeinen nicht empfohlen.

Auch in den Dokumenten:

Weak references are not supported in Mac OS X v10.6 and iOS 4.
rimsky
quelle
1
Ja das ist richtig, __unsafe_unretainedist die ARC Version von assign.
Robert
2

Die kristallklare Verwendung der WEAK-Eigenschaft ist wie folgt:

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;
Alen Alexander
quelle
1
Wenn ich meine Eigenschaften schwach benutze, erhalte ich die Warnung: "Schwacher Empfänger ist möglicherweise unvorhersehbar auf Null eingestellt." Ich habe einige andere Beiträge gesehen, in denen Sie eine starke lokale Referenz erstellen müssen, um diese Warnung zu verhindern. Und wenn dies zutrifft, was bringt es, eine Eigenschaft schwach zu machen, wenn ich am Ende eine starke Referenz erstellen muss?
Arh
0

Nehmen wir ein Beispiel, um mehr zu erläutern (die obigen Antworten sind bereits großartig). Möge dieses Beispiel wenig mehr helfen

Lassen Sie uns zwei Klassen A und B haben

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    {
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   }

Der obige Code generiert einen Aufbewahrungszyklus, da beide vom starken Typ a --------> b ---------> a sind

Um dies zu vermeiden, müssen Sie die Week-Eigenschaft eines dieser Objekte verwenden, damit es wöchentlich auf das Objekt verweist und nicht die Referenzanzahl erhöht.

Anurag Bhakuni
quelle