IBOutlet 和其他的弱或强 [英] weak or strong for IBOutlet and other

查看:21
本文介绍了IBOutlet 和其他的弱或强的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将我的项目切换到 ARC,但我不明白是否必须对 IBOutlets 使用 strongweak.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?当使用 strongweakunsafe_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 as weak.

@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 outlets weak 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 和其他的弱或强的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆