【发布时间】:2015-05-29 17:17:30
【问题描述】:
我无法理解 Objective-C 和 ARC。
据我了解,强指针会自动为您解除分配,因此您不必考虑它(在 dealloc 方法中解除分配,还是在上次使用对象之后?)。
所以我写了一个小应用程序,有 2 个 viewController 和一个 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方法,所有的弱指针都应该被niled
由于强指针只在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
【问题讨论】:
-
请注意,像这样的测试行为永远不会起作用。首先,像
@"it works"这样的静态字符串永远不会被释放,因为它从一开始就没有被分配;它是可执行映像的一部分。其次,即使对象被解除分配,向解除分配的对象发送消息也会表现出未定义的行为,并且不能保证会导致崩溃或其他症状。 -
什么意思,它从来没有分配过?那么它是像应用程序生命周期的“全局”变量还是......? _myString = @"it works" 与 _myString = [[[NSString alloc] initWithString:@"it works"] autorelease] 或类似的东西不一样吗?因为每当我尝试写这样的东西时,Xcode 都会向我显示写 _myString = @"it works" 的警告
-
@denis631 是的。但这与我在答案中使用
stringWithFormat:构建字符串的方式不同。 -
@denis631 由
@"..."创建的字符串实际上是在编译时创建的,是应用程序可执行文件的一部分。它与应用程序的其余数据(和代码)一起映射到内存中,因此,它不是应用程序分配堆的一部分。所述对象在释放或保留时不做任何事情,并且它们永远不会被释放,因为首先没有分配。使用 NSString(或其他框架类)经常会因为这个和其他(参见标记的指针)原因而感到困惑。在进行此类学习练习时,请始终使用您自己的NSObject子类!
标签: ios objective-c memory-management memory-leaks dealloc