ios - IBOutlet 和其他的弱或强

标签 ios ios5 automatic-ref-counting weak-references strong-references

<分区>

我已经将我的项目切换到 ARC,我不知道我是否必须为 IBOutlets 使用 strongweak。 Xcode 这样做:在界面生成器中,如果创建一个 UILabel,然后我将它与助理编辑器连接到我的 ViewController,它会创建这个:

@property (nonatomic, strong) UILabel *aLabel;

它使用 strong,我在 RayWenderlich 网站上阅读了这样的教程:

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;
}

所以使用weak,而不是strong,并在videDidUnload中移除设置为nil,Xcode使用 strong,并在 viewDidUnload 中使用 self... = nil

我的问题是:什么时候必须使用strong,什么时候使用weak? 我还想用于部署目标 iOS 4,那么什么时候必须使用 unsafe_unretain?当使用 strongweakunsafe_unretain 与 ARC 时,任何人都可以通过一个小教程帮助我很好地解释?

最佳答案

经验法则

当父对象引用子对象时,您应该使用strong 引用。当子对象引用其父对象时,您应该使用 weak 引用或 unsafe_unretained 引用(如果前者不可用)。一个典型的场景是当你与委托(delegate)打交道时。例如,UITableViewDelegate 不保留包含 TableView 的 Controller 类。

enter image description here

这里有一个简单的模式来展示主要概念。

假设第一个 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作者:Mike Ash

关于你的第二个问题,如果你需要支持 iOS 4,你必须使用 unsafe_unretained 而不是 weak

在 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?

using ARC, lifetime qualifier assign and unsafe_unretained

strong / weak / retain / unsafe_unretained / assign

希望对您有所帮助。

更新

根据 shaunlim 的评论,从 iOS 6 开始,viewDidUnload 方法已被弃用。这里真心建议看看Rob的回答:iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning? .

关于ios - IBOutlet 和其他的弱或强,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11168916/

相关文章:

ios - 使用 swift 中的按钮操作控制网页 View

iphone - jQuery Mobile 在 iPhone iOS 5 中不显示数据图标

XCode 4.2 NSManagedObject 上下文构建失败

objective-c - 为什么 ARC 仅适用于 iOS 4.0+?

objective-c - ARC引用计数解除分配和释放

objective-c - 如果我在从委托(delegate)访问我的 View 时得到 EXC_BAD_ACCESS,这是否意味着我有内存泄漏?

iOS 应用程序,以编程方式获取构建版本

ios - AVCaptureSession 音频不适用于长视频

ios - 当我为 iPhone 项目创建 .ipa 或二进制文件时图像消失

macos - 将旧代码从 OS X 10.6 更新到 10.7