我在理解Objective-C和ARC时遇到了问题。
据我所知,强指针会自动为你解除分配,所以你不必考虑它(在dealloc方法中解除分配,或者在最后一次使用对象之后?)。
所以我写了一个小应用程序,带有2个viewControllers和一个NavigationController,它进入一个视图然后返回。
调用了dealloc方法,但是我在viewDidLoad方法中设置的属性没有被释放,它仍然指向某个对象。
代码: 第一个viewController有一个按钮,通过按下它,可以执行另一个viewController的segue。那里没有代码。
SecondViewController.m
@interface SecondViewController ()
@property (nonatomic, strong) NSString *myString;
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@", _myString);
_myString = @"it works";
}
- (void)dealloc {
NSLog(@"%@", _myString);
// and now it is deallocating the _myString property ???
}
@end
然后,我试着做另一件事。
这个想法是创建一个弱指针,它指向与强指针相同的内存地址。不过,我认为弱指针在任何情况下都应为零。
由于调用dealloc方法,所有弱指针都应该被标记
由于强指针仅在viewDidLoad中使用,因此应在dealloc方法之前取消分配。
问题是,它没有被解除分配。 为什么?
secondViewController的代码:
@interface SecondViewController ()
@property (nonatomic, strong) NSString *myString;
@property (nonatomic, weak) NSString *test;
@end
@implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"%@", _myString);
_myString = @"it works";
_test = _myString;
}
- (void)dealloc
{
NSLog(@"%@", _test);
}
@end
答案 0 :(得分:3)
在dealloc方法结束时发生属性的释放。如果覆盖dealloc方法,则该方法中的属性尚未解除分配。
您可以通过在第一个视图控制器中创建一个weak属性来测试它,分配第二个视图控制器的strong属性,然后在应用程序返回到第一个视图控制器时记录它的值。
答案 1 :(得分:3)
说明weak
引用的最简单方法是使用以下示例...
鉴于以下两个类:
@interface ObjectWithStrongRef : NSObject
@property (strong) NSString *ref;
@end
@interface ObjectWithWeakRef : NSObject
@property (weak) NSString *ref;
@end
我们将创建一个ObjectWithWeakRef
的实例,其范围大于ObjectWithStrongRef
的范围,为后者的ref
属性赋值,然后使用前者' s ref
指向同一个对象,然后我们将检查两个范围中的ref
。
int main(int argc, const char * argv[]) {
ObjectWithWeakRef *weak = [[ObjectWithWeakRef alloc] init];
@autoreleasepool {
ObjectWithStrongRef *strong = [[ObjectWithStrongRef alloc] init];
strong.ref = [NSString stringWithFormat:@"Hello %@", @"World"];
weak.ref = strong.ref;
NSLog(@"Weak.Ref = %@", weak.ref);
}
NSLog(@"Weak.Ref = %@", weak.ref);
}
请注意,我们不能简单地将ref
分配给文字字符串。 Objective-C倾向于将它们保留在内存中,以便它可以进行一些内存优化,但是当我们使用stringWithFormat:
时,它会创建一个自动释放字符串。
在第一个NSLog
语句中,strong.ref
维护对字符串对象的强引用,因此当我们记录weak.ref
时,该对象尚未解除分配,因此它正确记录&# 34; Hello World"。
在第一次和第二次NSLog
来电之间,我们已退出@autoreleasepool
,其中strong
对象的作用域(如果我们发出NSLog
条消息在ObjectWithStrongRef
' dealloc
中,我们在这里看到了它。因为我们退出strong
时@autoreleasepool
已取消分配,所以我们不再引用对我们引用的字符串对象的强引用 - 我们只有weak
的弱引用到内存,所以字符串对象也解除分配(在strong
解除分配之后)。
因此,在第二次NSLog
来电中,我们会看到Weak.Ref = (null)
已打印出来。