3

我刚刚阅读了这个问题的公认优秀答案,它阐明了 Objective-C 中强指针和弱指针之间的概念差异,我仍在努力理解实际差异。我来自不存在这些概念的 C++ 背景,我无法弄清楚我将在哪里使用一个与另一个。

有人可以提供一个使用Objective-C代码的实际示例来说明强指针和弱指针的不同用途吗?

4

2 回答 2

8

概念

这都是关于保留计数的。ARC 是一种方便,可以避免开发者担心手动保留和释放。从本质上讲,强变量会将保留计数增加 1,而弱变量则不会。

见下文:

@interface Test () {
    NSString* strongVariable; // Instance variables default to strong
    __weak NSString* weakVariable;
}
@end

// This has a retain count of 1, it has been allocated to memory by the user, and stored in a local variable (which is strong)
NSString* str = [[NSString alloc] initWithString:@"Test"];

// The string object will now have a retain count of 2, as the strong variable has increased its retain count
strongVariable = str;

// This weak variable does **not** increase the retain count, and as such it will still be 2
weakVariable = str;

// --

// Now, lets remove some references
// This will reduce the retain count to 1, as a strong variable has lost its link
strongVariable = nil;

// This will also reduce the retain count, as another strong variable has lost it's reference. This means the retain count is 0, and the object can now be considered to not exist
str = nil;

// What happens to weakVariable?
// Because it is referencing an object with a 0 retain count, the runtime will set the value of this variable automatically to nil (iOS 5 and above).
NSLog(@"%@", (weakVariable == nil) ? @"nil" : @"Not nil") // Will print "nil"

您不能遇到强变量引用保留计数为 0 的对象的情况,这违背了强变量的核心概念。值得注意的是,旁边__weak还有__unsafe_unretained. 这就像一个弱变量,除了它不会在保留计数达到零时自动设置为 nil,这意味着它将包含一个指向内存随机部分的指针(如果你访问它会崩溃,你需要 nil 它你自己)。存在这种情况的原因是由于 iOS 4 支持 ARC,但不支持__weak. 在大多数情况下,您会使用__weak.

上面的描述只是一个实用的一瞥,您可以使用此文档更深入地阅读。

实际应用

一切都是__strong默认的。如果你想要弱,你需要使用__weak.

当您在概念上不想拥有特定对象时,通常会使用弱变量。虽然汽车将拥有它的引擎和车轮,但它不会拥有司机。

Wheel* wheel;
Engine* engine;
__weak Driver* driver;

相反,司机将拥有汽车。

Car* car;

如果汽车拥有司机,我们将有一个保留周期。汽车拥有司机,司机拥有汽车。如果我们要释放一个,另一个会发生什么?保留周期的整个概念超出了这个问题的范围,但你可以在这里阅读。

同样的概念也适用于编程模式,例如委托。对于表视图,视图控制器将拥有表视图,但表视图不拥有视图控制器(用作委托)

//ViewController
UITableView* tableView;
tableView.delegate = self;     

//UITableView
@property (nonatomic, weak) id<UITableViewDelegate> delegate;

陷阱

一种严重的用途__weak是在块内。没有它们,您将面临在不知不觉中导致保留周期的严重风险。同样,这超出了此问题的范围,但请参阅此处了解更多信息

类比 C++

在 TR1 中,您可以使用共享指针,它们允许您将堆分配的对象放入分配的堆栈中,并为我们管理内存。它通过使用引用计数来做到这一点。每次将共享指针传递给另一个变量时,引用计数都会增加。这类似于分配给 Obj-C 中的强变量。

于 2012-11-29T10:47:44.880 回答
1

根据我的发现,弱指针主要用于从子方面的父子关系。通过将指向其父级的指针设置为弱属性,子级将不拥有父级,您将避免所有权关系。

这篇文章帮助我理解了这些新概念,你应该看看它: http ://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1

于 2012-11-29T10:50:46.680 回答