为什么在 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

然后,我尝试做另一件事。

我们的想法是创建一个弱指针,它指向与强指针相同的内存地址。我虽然,弱指针在任何情况下都应该是零。

  1. 由于调用了dealloc方法,所有弱指针都应该被niled

  2. 由于强指针只在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

我们将创建一个范围大于 ObjectWithStrongRefObjectWithWeakRef 实例,为后者的 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 消息在 ObjectWithStrongRefdealloc 中,我们会看到它在这里被调用)。因为 strong 在我们退出 @autoreleasepool 时已经释放,所以不再有对我们引用的字符串对象的任何强引用——我们只有 weak 对内存的弱引用,因此字符串对象 解除分配(就在 strong 解除分配之后)。

因此在第二个 NSLog 调用中,我们将看到 Weak.Ref = (null) 打印。