深入了解Objective-C中强指针和弱指针的实际应用 [英] Getting my head around the practical applications of strong and weak pointers in Objective-C

查看:180
本文介绍了深入了解Objective-C中强指针和弱指针的实际应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚阅读了对此的公认的出色答案

I've just read the accepted excellent answer to this question that clarifies the conceptual differences between strong and weak pointers in Objective-C, and I'm still trying to understand the practical differences. I come from a C++ background where these concepts don't exist, and I'm having trouble figuring out where I would use one vs the other.

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

Could someone please provide a practical example, using Objective-C code, that illustrates the different uses of strong and weak pointers?

推荐答案

概念

所有与保留计数有关. ARC很方便,可以防止开发人员担心手动保留和释放.从本质上讲,强变量会使保留计数减少1,而弱变量则不会.

Concept

It's all about the retain counts. ARC is a convenience, to prevent developers worrying about manually retaining and releasing. At its core, a strong variable will knock up the retain count by 1, whereas a weak variable won't.

参见下文:

@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.

You can't get into a situation where a strong variable is referencing an object with a retain count of 0, that defies the core concept of a strong variable. It is worth noting, along side __weak, there is __unsafe_unretained. This acts just like a weak variable, except it isn't automatically set to nil once the retain count reaches zero, meaning it will contain a pointer to a random part of memory (and will crash if you access it, you need to nil it yourself). The reason this exists is due to iOS 4 supporting ARC, but not __weak. In most cases, you'd use __weak.

上面的描述只是实际的一瞥,您可以深入阅读

The above description is just a practical glance, you can read a lot more in depth using this documentation.

默认情况下,所有内容均为__strong.如果想要弱点,则需要使用__weak.

Everything is __strong by default. If you want weak, you need to use __weak.

当您从概念上不想拥有特定对象时,通常会使用弱变量.汽车虽然拥有自己的引擎和车轮,却不拥有驾驶员.

You would typically use weak variables when you conceptually don't want to own a particular object. Whilst a car would own its engine and wheels, it wouldn't own the driver.

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

相反,驾驶员将拥有汽车.

Conversely, a driver would own the Car.

Car* car;

如果汽车归驾驶员所有,我们将有一个保留周期.汽车拥有驾驶员,而驾驶员拥有汽车.如果我们要发布一个,那么另一个会发生什么呢?保留周期的整个概念超出了此问题的范围,但是您可以

If the car owned the driver, we would have a retain cycle. The car owns the driver, and the driver owns the car. If we were to release one, what would happen to the other? The whole concept of retain cycles outweighs the scope of this question, but you can read about it here.

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

The same concept applies to programming patterns, for example delegates. For a table view, the view controller would own the table view, but the table view doesn't own the view controller (Which is uses as a delegate)

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

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

陷阱

__weak的一种严重用法是在块内.没有它们,您将面临造成保留周期而没有意识到的严重风险.同样,这超出了此问题的范围,但是请参阅这里以获取更多信息.

Gotchas

One serious use of __weak is within blocks. Without them, you're at serious risk of causing retain cycles without realising. Again, this outweighs the scope of this question, but see here for more information.

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

Within TR1 you have the ability to use shared pointers, these allow you to put a heap allocated object within a stack allocated one, and it manages the memory for us. It does this through the use of reference counting. Everytime you pass the shared pointer to another variable, the reference count is incremented. This analogises to assigning to a strong variable in Obj-C.

这篇关于深入了解Objective-C中强指针和弱指针的实际应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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