我刚刚阅读了这个问题的公认优秀答案,澄清了Objective-C中强弱指针之间的概念差异,我仍然试图理解实际差异.我来自C++背景,这些概念不存在,我无法弄清楚我将使用哪一个与另一个相比.
有人可以提供一个实际的例子,使用Objective-C代码,说明强弱指针的不同用途吗?
这完全取决于保留计数.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"
Run Code Online (Sandbox Code Playgroud)
您无法进入强变量引用保留计数为0的对象的情况,这会违反强变量的核心概念.值得注意的是,旁边__weak
有__unsafe_unretained
.这就像一个弱变量,除了保留计数达到零后它不会自动设置为nil,这意味着它将包含一个指向内存随机部分的指针(如果你访问它会崩溃,你需要将它取消你自己).之所以存在,是因为iOS 4支持ARC,但不是__weak
.在大多数情况下,你会使用__weak
.
一切都是__strong
默认的.如果你想要弱,你需要使用__weak
.
当您在概念上不想拥有特定对象时,通常会使用弱变量.虽然汽车拥有发动机和车轮,但它不会拥有驾驶员.
Wheel* wheel;
Engine* engine;
__weak Driver* driver;
Run Code Online (Sandbox Code Playgroud)
相反,司机会拥有汽车.
Car* car;
Run Code Online (Sandbox Code Playgroud)
如果汽车拥有驱动程序,我们将有一个保留周期.汽车拥有司机,司机拥有汽车.如果我们要释放一个,另一个会发生什么?保留周期的整个概念超出了这个问题的范围,但你可以在这里阅读它.
相同的概念适用于编程模式,例如委托.对于表视图,视图控制器将拥有表视图,但表视图不拥有视图控制器(用作委托)
//ViewController
UITableView* tableView;
tableView.delegate = self;
//UITableView
@property (nonatomic, weak) id<UITableViewDelegate> delegate;
Run Code Online (Sandbox Code Playgroud)
一个严重的用途__weak
是在块内.如果没有它们,你很有可能在没有意识到的情况下导致保留周期.同样,这超出了这个问题的范围,但请参阅此处以获取更多信息.
在TR1中你可以使用共享指针,这些允许你将堆分配的对象放在一个分配的堆栈中,并为我们管理内存.它通过使用引用计数来实现.每次将共享指针传递给另一个变量时,引用计数都会递增.这类似于在Obj-C中分配强变量.
归档时间: |
|
查看次数: |
206 次 |
最近记录: |