問題描述
我已將我的項目切換到 ARC,但我不明白是否必須對 IBOutlets 使用 strong
或 weak
.Xcode 這樣做:在界面生成器中,例如,如果創(chuàng)建一個 UILabel
并且我將它與助手編輯器連接到我的 ViewController
,它會創(chuàng)建這個:
@property (nonatomic, strong) UILabel *aLabel;
它使用 strong
,相反,我在 RayWenderlich 網(wǎng)站上閱讀了一個教程,上面寫著:
但是對于這兩個特定的屬性,我還有其他計劃.代替strong
,我們將它們聲明為weak
.
@property (nonatomic, weak) IBOutlet UITableView *tableView;@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
<塊引用>
Weak
是所有 outlet 屬性的推薦關系.這些視圖對象已經(jīng)是視圖控制器視圖的一部分層次結(jié)構(gòu),不需要在其他地方保留.最大的優(yōu)勢聲明你的 outlet weak
的好處是它可以節(jié)省你編寫viewDidUnload 方法.
目前我們的 viewDidUnload
看起來像這樣:
- (void)viewDidUnload{[超級 viewDidUnload];self.tableView = nil;self.searchBar = nil;音效 = 無;}
<塊引用>
您現(xiàn)在可以將其簡化為以下內(nèi)容:
- (void)viewDidUnload{[超級 viewDidUnload];音效 = 無;}
所以使用weak
,而不是strong
,并去掉videDidUnload
中的設置為nil,代替Xcode使用strong
,并在 viewDidUnload
中使用 self... = nil
.
我的問題是:我什么時候必須使用strong
,什么時候使用weak
?我也想用于部署目標 iOS 4,那么我什么時候必須使用 unsafe_unretain
?當使用 strong
、weak
和 unsafe_unretain
與 ARC 時,任何人都可以通過一個小教程幫助我很好地解釋我?
經(jīng)驗法則
當父對象引用子對象時,您應該使用 strong
引用.當子對象具有對其父對象的引用時,您應該使用 weak
引用或 unsafe_unretained
引用(如果前者不可用).一個典型的場景是當您與代表打交道時.例如,UITableViewDelegate
不保留包含表格視圖的控制器類.
這里有一個簡單的模式來展示主要概念.
假設第一個 A、B 和 C 是 strong
引用.特別是,C 對其父級有一個 strong
引用.當 obj1 被釋放(某處)時,A 引用不再存在,但您有泄漏,因為 obj1 和 obj2 之間存在循環(huán).就保留計數(shù)而言(僅用于解釋目的),obj1 的保留計數(shù)為 2(obj2 有一個 strong
引用),而 obj2 有一個保留計數(shù)of 1. 如果 obj1 被釋放,它的保留計數(shù)現(xiàn)在是 1,并且它的 dealloc
方法沒有被調(diào)用.obj1 和 obj2 仍然保留在內(nèi)存中,但沒有人引用它們:Leak.
反過來說,如果只有 A 和 B 是 strong
refs 并且 C 被限定為 weak
一切都可以.你沒有泄漏.事實上,當 obj1 被釋放時,它也釋放了 obj2.就保留計數(shù)而言,obj1 的保留計數(shù)為 1,obj2 的保留計數(shù)為 1.如果 obj1 被釋放,它的保留計數(shù)現(xiàn)在為 0,并調(diào)用其 dealloc
方法.obj1 和 obj2 從內(nèi)存中刪除.
一個簡單的建議:在處理 ARC 時開始考慮對象圖.
關于您的第一個問題,當您處理 XIB 時,兩種解決方案都有效.通常在處理內(nèi)存周期時會使用 weak
引用.關于 XIBs 文件,如果你使用 strong
你需要在 viewDidUnload
中設置 nil
因為如果你不這樣做,在內(nèi)存不足的情況下,您可能會導致意外泄漏.您不會在 dealloc
中釋放它們,因為 ARC 會為您完成.weak
不需要這種處理,因為當目標對象被銷毀時,這些值會自動設置為 nil
.不再有懸空指針.
如果你有興趣,我真的建議你閱讀friday-qa-2012-04-13-nib-memory-management by Mike Ash.
關于你的第二個問題,如果你需要支持 iOS 4,你必須使用 unsafe_unretained
而不是 weak
.
在 SO 中有很多問題/答案.這里是主要的:
如何在使用 ARC 并針對 iOS 4.0 時,我應該替換弱引用嗎?
什么樣的Objective-C 中的自動引用計數(shù)不能防止或減少泄漏嗎?
使用 ARC、生命周期限定符 assign 和 unsafe_unretained
strong/weak/retain/unsafe_unretained/assign
希望對您有所幫助.
更新
根據(jù) shaunlim 的評論,從 iOS 6 開始,viewDidUnload
方法已被棄用.這里我真的建議看看 Rob 的回答:iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?.
I have switched my project to ARC, and I don't understand if I have to use strong
or weak
for IBOutlets. Xcode do this: in interface builder, if a create a UILabel
for example and I connect it with assistant editor to my ViewController
, it create this:
@property (nonatomic, strong) UILabel *aLabel;
It uses the strong
, instead I read a tutorial on RayWenderlich website that say this:
But for these two particular properties I have other plans. Instead of
strong
, we will declare them asweak
.
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
Weak
is the recommended relationship for all outlet properties. These view objects are already part of the view controller’s view hierarchy and don’t need to be retained elsewhere. The big advantage of declaring your outletsweak
is that it saves you time writing the viewDidUnload method.Currently our
viewDidUnload
looks like this:
- (void)viewDidUnload
{
[super viewDidUnload];
self.tableView = nil;
self.searchBar = nil;
soundEffect = nil;
}
You can now simplify it to the following:
- (void)viewDidUnload
{
[super viewDidUnload];
soundEffect = nil;
}
So use weak
, instead of the strong
, and remove the set to nil in the videDidUnload
, instead Xcode use the strong
, and use the self... = nil
in the viewDidUnload
.
My question is: when do I have to use strong
, and when weak
?
I want also use for deployment target iOS 4, so when do I have to use the unsafe_unretain
? Anyone can help to explain me well with a small tutorial, when use strong
, weak
and unsafe_unretain
with ARC?
A rule of thumb
When a parent has a reference to a child object, you should use a strong
reference. When a child has a reference to its parent object, you should use a weak
reference or a unsafe_unretained
one (if the former is not available). A typical scenario is when you deal with delegates. For example, a UITableViewDelegate
doesn't retain a controller class that contains a table view.
Here a simple schema to present the main concepts.
Suppose first A,B and C are strong
references. In particular, C has a strong
ref to its parent. When obj1 is released (somewhere), the A reference doesn't exist anymore but you have a leak since there is a cycle between obj1 and obj2. Speaking in terms of retain counts (only for explain purposes), obj1 has a retain count of 2 (obj2 has a strong
reference to it), while obj2 has a retain count of 1. If obj1 is released, its retain count is now 1 and its dealloc
method is not called. obj1 and obj2 still remain in memory but no one has a reference to them: Leak.
On the contary, if only A and B are strong
refs and C is qualified as weak
all is ok. You have no leaks. In fact, when obj1 is released, it also releases obj2. Speaking in terms of retain counts, obj1 has a retain count of 1, obj2 has a retain count of 1. If obj1 is released, its retain count is now 0 and its dealloc
method is called. obj1 and obj2 are removed from memory.
A simple suggestion: Start to think in terms of object graph when you deal with ARC.
About your first question, both solutions are valid when you deal with XIBs. In general weak
references are used when you deal with memory cycles.
Concerning XIBs files, if you use strong
you need to set nil
in viewDidUnload
since if you don't do it, in memory low conditions, you could cause unexpected leaks. You don't release them in dealloc
because ARC will do it for you.
weak
instead doesn't need that treatment since, when the target object is destroyed, those values are set as nil
automatically. No dangling pointers anymore.
If you are interested in, I really suggest you to read friday-qa-2012-04-13-nib-memory-management by Mike Ash.
About your second question, if you need to support iOS 4, instead of weak
you have to use unsafe_unretained
.
Within SO there are a lot of questions/answers. Here the main ones:
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
Hope that helps.
Update
As per shaunlim's comment, starting from iOS 6 viewDidUnload
method is deprecated. Here I really suggest to see Rob's answer: iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?.
這篇關于IBOutlet 和其他的弱或強的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!