问题描述
我已将我的项目切换到 ARC,但我不明白是否必须对 IBOutlets 使用 strong
或 weak
.Xcode 这样做:在界面生成器中,例如,如果创建一个 UILabel
并且我将它与助手编辑器连接到我的 ViewController
,它会创建这个:
@property (nonatomic, strong) UILabel *aLabel;
它使用 strong
,相反,我在 RayWenderlich 网站上阅读了一个教程,上面写着:
但是对于这两个特定的属性,我还有其他计划.代替strong
,我们将它们声明为weak
.
@property (nonatomic, weak) IBOutlet UITableView *tableView;@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
<块引用>
Weak
是所有 outlet 属性的推荐关系.这些视图对象已经是视图控制器视图的一部分层次结构,不需要在其他地方保留.最大的优势声明你的 outlet weak
的好处是它可以节省你编写viewDidUnload 方法.
目前我们的 viewDidUnload
看起来像这样:
- (void)viewDidUnload{[超级 viewDidUnload];self.tableView = nil;self.searchBar = nil;音效 = 无;}
<块引用>
您现在可以将其简化为以下内容:
- (void)viewDidUnload{[超级 viewDidUnload];音效 = 无;}
所以使用weak
,而不是strong
,并去掉videDidUnload
中的设置为nil,代替Xcode使用strong
,并在 viewDidUnload
中使用 self... = nil
.
我的问题是:我什么时候必须使用strong
,什么时候使用weak
?我也想用于部署目标 iOS 4,那么我什么时候必须使用 unsafe_unretain
?当使用 strong
、weak
和 unsafe_unretain
与 ARC 时,任何人都可以通过一个小教程帮助我很好地解释我?
经验法则
当父对象引用子对象时,您应该使用 strong
引用.当子对象具有对其父对象的引用时,您应该使用 weak
引用或 unsafe_unretained
引用(如果前者不可用).一个典型的场景是当您与代表打交道时.例如,UITableViewDelegate
不保留包含表格视图的控制器类.
这里有一个简单的模式来展示主要概念.
假设第一个 A、B 和 C 是 strong
引用.特别是,C 对其父级有一个 strong
引用.当 obj1 被释放(某处)时,A 引用不再存在,但您有泄漏,因为 obj1 和 obj2 之间存在循环.就保留计数而言(仅用于解释目的),obj1 的保留计数为 2(obj2 有一个 strong
引用),而 obj2 有一个保留计数of 1. 如果 obj1 被释放,它的保留计数现在是 1,并且它的 dealloc
方法没有被调用.obj1 和 obj2 仍然保留在内存中,但没有人引用它们:Leak.
反过来说,如果只有 A 和 B 是 strong
refs 并且 C 被限定为 weak
一切都可以.你没有泄漏.事实上,当 obj1 被释放时,它也释放了 obj2.就保留计数而言,obj1 的保留计数为 1,obj2 的保留计数为 1.如果 obj1 被释放,它的保留计数现在为 0,并调用其 dealloc
方法.obj1 和 obj2 从内存中删除.
一个简单的建议:在处理 ARC 时开始考虑对象图.
关于您的第一个问题,当您处理 XIB 时,两种解决方案都有效.通常在处理内存周期时会使用 weak
引用.关于 XIBs 文件,如果你使用 strong
你需要在 viewDidUnload
中设置 nil
因为如果你不这样做,在内存不足的情况下,您可能会导致意外泄漏.您不会在 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 中的自动引用计数不能防止或减少泄漏吗?
使用 ARC、生命周期限定符 assign 和 unsafe_unretained
strong/weak/retain/unsafe_unretained/assign
希望对您有所帮助.
更新
根据 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 和其他的弱或强的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!