ios IBOutlet 和其他的弱或强
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11168916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
weak or strong for IBOutlet and other
提问by Piero
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:
我已经将我的项目切换到 ARC,我不明白我是否必须使用IBOutletsstrong
或weak
IBOutlets。Xcode 这样做:在界面构建器中,如果创建一个UILabel
例如,我将它与助手编辑器连接到我的ViewController
,它会创建这个:
@property (nonatomic, strong) UILabel *aLabel;
It uses the strong
, instead I read a tutorial on RayWenderlich website that say this:
它使用strong
,而不是我在 RayWenderlich 网站上阅读了一个教程,它说:
But for these two particular properties I have other plans. Instead of
strong
, we will declare them asweak
.
但是对于这两个特定的属性,我有其他计划。取而代之的是
strong
,我们将它们声明为weak
.
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
Weak
is the recommended relationship for all outletproperties. 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:
Weak
是所有插座属性的推荐关系。这些视图对象已经是视图控制器视图层次结构的一部分,不需要保留在其他地方。声明您的插座的一大优点weak
是它可以节省您编写 viewDidUnload 方法的时间。目前我们的
viewDidUnload
样子是这样的:
- (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
.
所以使用weak
,而不是strong
,并删除设置为nil的videDidUnload
,而不是Xcode的使用strong
,以及使用self... = nil
的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?
我的问题是:我什么时候必须使用strong
,什么时候使用weak
?我还想用于部署目标 iOS 4,那么我什么时候必须使用unsafe_unretain
? 任何人都可以帮助解释我还有一个小教程,在使用时strong
,weak
以及unsafe_unretain
与ARC?
回答by Lorenzo B
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.
当父对象引用子对象时,您应该使用strong
引用。当子对象有对其父对象的引用时,您应该使用一个weak
引用或一个引用 unsafe_unretained
(如果前者不可用)。一个典型的场景是当你处理委托时。例如, aUITableViewDelegate
不保留包含表视图的控制器类。
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.
假设第一个 A、B 和 C 是strong
引用。特别是,C 有一个strong
对其父级的引用。当 obj1 被释放(某处)时,A 引用不再存在,但由于 obj1 和 obj2 之间存在循环,因此存在泄漏。就保留计数而言(仅用于说明目的),obj1 的保留计数为 2(obj2 对其有strong
引用),而 obj2 的保留计数为 1。如果 obj1 被释放,其保留计数现在为 1,并且它的dealloc
方法没有被调用。obj1 和 obj2 仍然保留在内存中,但没有人引用它们: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 和 B 是strong
refs 并且 C 是合格的,那么weak
一切都可以。你没有泄漏。事实上,当obj1被释放时,它也会释放obj2。说到retain counts,obj1的retain count为1,obj2的retain count为1。如果obj1被释放,它的retain count现在为0,并且dealloc
调用了它的方法。obj1 和 obj2 从内存中删除。
A simple suggestion: Start to think in terms of object graph when you deal with ARC.
一个简单的建议:在处理 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.
关于您的第一个问题,当您处理 XIB 时,这两种解决方案都是有效的。通常weak
在处理内存周期时使用引用。关于XIBs文件,如果你使用strong
你需要设置nil
,viewDidUnload
因为如果你不这样做,在内存不足的情况下,你可能会导致意外泄漏。你不会释放它们,dealloc
因为 ARC 会为你做。
weak
相反,不需要这种处理,因为当目标对象被销毁时,这些值会nil
自动设置。不再有悬空指针。
If you are interested in, I really suggest you to read friday-qa-2012-04-13-nib-memory-managementby Mike Ash.
如果你有兴趣,我真的建议你阅读周五-QA-2012-04-13-笔尖内存管理由迈克灰。
About your second question, if you need to support iOS 4, instead of weak
you have to use unsafe_unretained
.
关于你的第二个问题,如果你需要支持 iOS 4,而不是weak
你必须使用unsafe_unretained
.
Within SO there are a lot of questions/answers. Here the main ones:
在 SO 中有很多问题/答案。这里主要的:
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?
Objective-C 中的自动引用计数不能防止或最小化哪种泄漏?
using ARC, lifetime qualifier assign and unsafe_unretained
使用 ARC、生命周期限定符分配和 unsafe_unretained
strong / weak / retain / unsafe_unretained / assign
强 / 弱 / 保留 / unsafe_unretained / 分配
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?.
根据 shaunlim 的评论,从 iOS 6 开始的viewDidUnload
方法已被弃用。在这里我真的建议看看 Rob 的回答:iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning? .
回答by dasdom
You can use weak for objects which are connected via IBOutlets to objects in IB because in this case the objects will be there as long as the superview is there. This is because the superview has a strong pointer to its subviews.
您可以将弱对象用于通过 IBOutlets 连接到 IB 中的对象,因为在这种情况下,只要超级视图在那里,对象就会在那里。这是因为超视图有一个指向其子视图的强指针。
If the pointer you are defining is the only pointer to an object you should declare it as strong.
如果您定义的指针是指向对象的唯一指针,则应将其声明为强指针。
If you are a registered developer I strongly recommend that you have a look into the videos from the WWDC11 and WWDC12. Another good resource is the iOS development podcast from Stanford.
如果您是注册开发人员,我强烈建议您查看 WWDC11 和 WWDC12 的视频。另一个很好的资源是来自斯坦福的 iOS 开发播客。