为什么在 dealloc 方法中没有释放对象?
Why objects are not dealloced in the dealloc method?
我无法理解 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方法,所有弱指针都应该被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
属性的释放发生在 dealloc 方法的末尾。如果覆盖 dealloc 方法,属性将不会在该方法内被释放。
您可以通过在第一个视图控制器中创建一个弱 属性 来测试它,分配第二个视图控制器的强 属性,然后在应用程序 [=15] 时记录它的值=]到第一个视图控制器。
说明 weak
引用的最简单方法是使用以下示例...
给定以下两个 类:
@interface ObjectWithStrongRef : NSObject
@property (strong) NSString *ref;
@end
@interface ObjectWithWeakRef : NSObject
@property (weak) NSString *ref;
@end
我们将创建一个范围大于 ObjectWithStrongRef
的 ObjectWithWeakRef
实例,为后者的 ref
属性 赋值,然后让前者的 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
时,对象还没有被释放,所以它正确记录"Hello World".
在第一个和第二个 NSLog
调用之间,我们退出了 @autoreleasepool
,其中 strong
对象被限定(如果我们放置一个 NSLog
消息在 ObjectWithStrongRef
的 dealloc
中,我们会看到它在这里被调用)。因为 strong
在我们退出 @autoreleasepool
时已经释放,所以不再有对我们引用的字符串对象的任何强引用——我们只有 weak
对内存的弱引用,因此字符串对象 也 解除分配(就在 strong
解除分配之后)。
因此在第二个 NSLog
调用中,我们将看到 Weak.Ref = (null)
打印。
我无法理解 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方法,所有弱指针都应该被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
属性的释放发生在 dealloc 方法的末尾。如果覆盖 dealloc 方法,属性将不会在该方法内被释放。
您可以通过在第一个视图控制器中创建一个弱 属性 来测试它,分配第二个视图控制器的强 属性,然后在应用程序 [=15] 时记录它的值=]到第一个视图控制器。
说明 weak
引用的最简单方法是使用以下示例...
给定以下两个 类:
@interface ObjectWithStrongRef : NSObject
@property (strong) NSString *ref;
@end
@interface ObjectWithWeakRef : NSObject
@property (weak) NSString *ref;
@end
我们将创建一个范围大于 ObjectWithStrongRef
的 ObjectWithWeakRef
实例,为后者的 ref
属性 赋值,然后让前者的 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
时,对象还没有被释放,所以它正确记录"Hello World".
在第一个和第二个 NSLog
调用之间,我们退出了 @autoreleasepool
,其中 strong
对象被限定(如果我们放置一个 NSLog
消息在 ObjectWithStrongRef
的 dealloc
中,我们会看到它在这里被调用)。因为 strong
在我们退出 @autoreleasepool
时已经释放,所以不再有对我们引用的字符串对象的任何强引用——我们只有 weak
对内存的弱引用,因此字符串对象 也 解除分配(就在 strong
解除分配之后)。
因此在第二个 NSLog
调用中,我们将看到 Weak.Ref = (null)
打印。