31

Ich habe mein Projekt auf ARC geschaltet, und ich verstehe nicht, ob ich strong oder weak für IBOutlets verwenden muss. Xcode dies tun: in Interface Builder, wenn ein ein UILabel zum Beispiel schaffen und ich verbinde es mit Schnittassistenz meiner ViewController, es folgt zu erstellen:schwach oder stark für IBOutlet und andere

@property (nonatomic, strong) UILabel *aLabel; 

Es nutzt die strong, stattdessen las ich ein Tutorial auf RayWenderlich Website das sagen:

Aber für diese beiden besonderen Eigenschaften habe ich andere Pläne. Anstelle von strong werden wir sie als weak deklarieren.

@property (nonatomic, weak) IBOutlet UITableView *tableView; 
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar; 

Weak ist das empfohlene Verhältnis für alle Auslass Eigenschaften. Diese Ansichtsobjekte sind bereits Teil der View-Hierarchie des View-Controllers und müssen nicht an anderer Stelle gespeichert werden. Der große Vorteil des Erklärens Ihrer Steckdosen weak ist, dass es Ihnen Zeit spart, die viewDidUnload Methode zu schreiben.

Zurzeit sind unsere viewDidUnload sieht wie folgt aus:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    self.tableView = nil; 
    self.searchBar = nil; 
    soundEffect = nil; 
} 

Sie jetzt an folgende vereinfachen kann:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    soundEffect = nil; 
} 

So weak, anstelle des strong und entferne den Satz auf null in videDidUnload, stattdessen verwende Xcode th e strong, und verwenden Sie die self... = nil in der viewDidUnload.

Meine Frage ist: Wann muss ich strong verwenden, und wenn weak? Ich möchte auch für die Bereitstellung von Ziel iOS 4 verwenden, also wann muss ich die unsafe_unretain verwenden? Wer kann mir helfen, mich mit einem kleinen Tutorial gut zu erklären, wenn man mit ARC strong, weak und unsafe_unretain benutzt?

Antwort

69

Eine Daumenregel

Wenn ein Elternteil einen Verweis auf ein untergeordnetes Objekt hat, sollten Sie eine strong Referenz verwenden. Wenn ein Kind eine Referenz auf sein Elternobjekt hat, sollten Sie eine weak Referenz oder eine eine verwenden (wenn die erste nicht verfügbar ist). Ein typisches Szenario ist, wenn Sie mit Delegierten umgehen. Beispiel: Eine UITableViewDelegate behält keine Controller-Klasse bei, die eine Tabellenansicht enthält.

enter image description here

Hier ist ein einfaches Schema der wichtigsten Konzepte zu präsentieren.

Angenommen, erste A, B und C sind strong Referenzen. Insbesondere hat C eine strong ref zu seinem Elternteil. Wenn obj1 (irgendwo) freigegeben wird, existiert die A-Referenz nicht mehr, aber Sie haben ein Leck, da es einen Zyklus zwischen obj1 und obj2 gibt. In Bezug auf Retain Counts (nur für Erklärungszwecke), obj1 hat eine Retain-Anzahl von 2 (Obj2 hat einen strong Verweis darauf), während Obj2 eine Retain-Anzahl von 1 hat. Wenn Obj1 freigegeben ist, ist seine Retain-Anzahl jetzt 1 und seine dealloc Methode wird nicht aufgerufen. Obj1 und Obj2 bleiben noch im Speicher, aber niemand hat einen Verweis auf sie: Leak.

Auf der gegenüberliegenden, wenn nur A und B sind strong refs und C ist als weak qualifiziert ist alles in Ordnung. Du hast keine Lecks. Wenn obj1 freigegeben wird, wird auch obj2 freigegeben. In Bezug auf Retain-Zählungen hat obj1 eine Retain-Zählung von 1, obj2 eine Retain-Zählung von 1. Wenn obj1 freigegeben wird, ist sein Retain-Zählwert jetzt 0 und seine dealloc-Methode wird aufgerufen. obj1 und obj2 werden aus dem Speicher entfernt.

Ein einfacher Vorschlag: Fangen Sie an, in Bezug auf Objektgraph zu denken, wenn Sie mit ARC umgehen.

Über Ihre erste Frage sind beide Lösungen gültig, wenn Sie mit XIBs arbeiten. Im Allgemeinen werden weak Referenzen verwendet, wenn Sie mit Speicherzyklen arbeiten. Wenn Sie XIBs-Dateien verwenden, müssen Sie strongnil in viewDidUnload setzen, denn wenn Sie dies nicht tun, können Sie unter niedrigen Speicherbedingungen zu unerwarteten Lecks führen. Sie geben sie nicht in dealloc frei, weil ARC es für Sie tun wird. weak benötigt diese Behandlung nicht, da diese Werte beim Löschen des Zielobjekts automatisch auf nil gesetzt werden. Keine baumelnden Zeiger mehr. Wenn Sie interessiert sind, empfehle ich Ihnen wirklich zu lesen friday-qa-2012-04-13-nib-memory-management von Mike Ash.

Über Ihre zweite Frage, wenn Sie iOS 4 unterstützen müssen, statt weak müssen Sie unsafe_unretained verwenden.

Innerhalb von SO gibt es viele Fragen/Antworten.Hier die wichtigsten:

How do I replace weak references when using ARC and targeting iOS 4.0?

What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?

using ARC, lifetime qualifier assign and unsafe_unretained

strong/weak/retain/unsafe_unretained/assign

Hoffnung, das hilft.

aktualisieren

Wie pro Kommentar des shaunlim von iOS 6 viewDidUnload Methode veraltet beginnt. Hier empfehle ich Robs Antwort: iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?.

+0

danke für die antwort – Piero

+0

du sagst das, für iboutlet wenn ich stark benutze muss ich nil in viewdidunload verwenden, und für wenig speicher habe ich keine leckstellen, stattdessen mit schwachem muss ich nil nicht in videwdidunlaod verwenden, und für wenig speicher warnen, es ist besser, die starke Lösung oder die schwache? – Piero

+0

Es ist das gleiche. Mit 'schwach' können Sie Zeit beim Schreiben von Code (zwei Zeilen in Ihrem Fall) von Hand sparen. Aber Xcode macht es für Sie. Meine persönliche Meinung. Ich benutze gerne 'stark'. –

11

Sie können weak für Objekte verwenden, die über IBOutlets mit Objekten in IB verbunden sind, da in diesem Fall die Objekte vorhanden sind, solange die Superview vorhanden ist. Dies liegt daran, dass die Superview einen starken Zeiger auf ihre Unteransichten hat.

Wenn der Zeiger, den Sie definieren, der einzige Zeiger auf ein Objekt ist, sollten Sie ihn als stark deklarieren.

Wenn Sie ein registrierter Entwickler sind, empfehlen wir dringend, dass Sie sich die Videos von WWDC11 und WWDC12 ansehen.Eine weitere gute Quelle ist die iOS-Entwicklung Podcast von Stanford.

+0

Sind die WWDC12 Videos schon verfügbar? – borrrden

+0

Ja, das sind sie! Wirklich schnell in diesem Jahr. – dasdom

+0

ok, aber ich verstehe nicht, meine Frage Abdeckung auch unsafe_unretain, aber für IBOutlet erkläre ich gut, warum Apple verwenden stark? ... statt schwach zu verwenden? ... so muss ich folgen Apfel? oder folge dem raywendlich Tutorial, wo ich oberhalb eines Snippets schreibe, das schwach verwendet? – Piero

Verwandte Themen