我正在使用 ARC 在 Objective-C 中开发应用。
我的简化代码如下所示:
A 类 (.m)
MyCustomClass *obj = [[MyCustomClass alloc] initWithValue1:@"abc" value2:1000];
MyViewController *vc = [[MyViewController alloc] initWithObject:obj];
// "vc" will become the first item of a UITabBarController
MyViewController (.h)
- (id)initWithObject:(MyCustomClass *)obj {
...
localReferenceToOjbect = obj;
...
}
- (void)viewWillAppear:(BOOL)animated {
// do something with "localRefernceToObject" <---
}
启动应用程序将导致调用僵尸:当显示 ViewController 时,“obj”将已被释放,因此我不能再使用它了。
我的解决方法是:
A 类 (.h)
@interface ClassA : UIViewController {
MyCustomClass *obj;
}
A 类 (.m)
obj = [[MyCustomClass alloc] initWithValue1:@"abc" value2:1000];
MyViewController *vc = [[MyViewController alloc] initWithObject:obj];
// "vc" will become the first item of a UITabBarController
这是正确的方法吗?!我不这么认为:为什么我必须存储一个对 ClassA 无用的对象?
我无法解释实际发生的事情。你能帮帮我吗?
最佳答案
事实上,在 ClassA 中保留对 obj 的引用是不合逻辑的。
但是如果您需要保留对 obj 的引用以便 MyViewController 使用它,请将其保留在 MyViewController 中,而不是在 ClassA 中,因为 MyViewController 将使用它。
最简单的方法是将您在 MyViewController
中使用的 localReferenceToObject
转换为 @property(retain) propertyToObject;
(或@property(strong) propertyToObject
如果你使用 ARC)并在你的 MyViewController.m
中使用 self.propertyToObject
访问它(而不是 localReferenceToObject
,以确保调用属性的 setter ,从而真正保留对象)。
这样,当您的 MyViewController
实例仍然存在时,该对象将被保留并保留。
[编辑] 如果您希望此属性是私有(private)的,您可以在类扩展中声明它,以便其他类无法访问它,如下例所示。参见 here in Apple's documentation了解更多详情。
在你的 MyViewController.h 头文件中
@interface MyViewController : UIViewController
// Here you write the public API in the .h / public header
// If you don't want your property to be visible, don't declare it there
@end
在你的 MyViewController.m 文件中
@interface MyViewController ()
// This is the private API, only visible inside the MyViewController.m file and not from other classes
// Note the "()" to declare the class extension, as explained in Apple doc
@property(nonatomic, retain) MyCustomClass* referenceToObject; // Note: use strong (which is a synonym of retain) if you use ARC
@end
@implementation MyViewController
@synthesize referenceToObject = _referenceToObject; // not even needed with modern ObjC and latest LLVM compiler
- (id)initWithObject:(MyCustomClass *)obj
{
self = [super init];
if (self) {
...
self.referenceToOjbect = obj;
...
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// do something with "self.refernceToObject"
}
// This memory management code is only needed if you don't use ARC
-(void)dealloc
{
self.referenceToObject = nil; // release memory
[super dealloc];
}
就我个人而言,正如 Apple 在某些 WWDC session 中所建议的那样,我现在真的很少使用实例变量,而更喜欢使用属性,无论是在 .h 中公开还是在 .m 中私有(private)。
如果您使用 ARC,您仍然可以使用实例变量而不是属性,因为 ARC 会为您保留它,但只要您确保您的实例变量被声明为 strong
而不是 weak
。
关于Objective-C:为什么自定义对象会变成僵尸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12951093/