奇怪的ARC问题没有在UIView子类中释放ivar

mat*_*way 5 objective-c ios automatic-ref-counting

可能重复:
使用ARC + NSZombieEnabled时,为什么对象未被释放

我在项目中遇到了一个非常奇怪的问题.简单地说,我ViewA拥有ViewB(strong财产).在其初始化中ViewA创建它ViewB.两个对象都是子类UIView.

dealloc在两者中都被覆盖了,并设置了一条日志线和一个断点来查看它们是否被击中.似乎ViewAdealloc被击中,但不是ViewB的.但是,如果我把一个self.viewB = nildeallocViewA,然后它击中.

所以基本上它是这样的:

@interface ViewA : UIView
@property (nonatomic, strong) ViewB *viewB;
@end

@implementation ViewA

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.viewB = [[ViewB alloc] initWithFrame:self.bounds];
        [self addSubview:self.viewB];
    }
    return self;
}

- (void)dealloc {
    //self.viewB = nil; ///< Toggling this commented/uncommented changes if ViewB's dealloc gets called.
    NSLog(@"ViewA dealloc");
}

@end
Run Code Online (Sandbox Code Playgroud)

我无法理解的是为什么viewB出局会产生影响.如果还有别的东西,viewB那么如果我把它弄到这里或者不在这里,它应该完全没有区别.并且它不应该对ARC添加的版本数量产生影响.

我似乎无法在最小的测试用例中重现它,但我正在研究它.不幸的是,我无法发布我看到的实际代码.我不认为这是一个问题,因为更重要的是,将它排除在外应该不会让我感到困惑.

任何人都可以看到我忽略的任何东西,或提供有关在哪里寻找调试此问题的建议?

更新:

我发现了这个问题.似乎只有在NSZombieEnabled设置时才会出现问题YES.那是完全疯了,肯定是一个错误.据我所知,僵尸不应该影响它的工作方式.对象仍然应该通过该dealloc方法.而且更重要的是,它只是疯了,它的工作原理,如果我无出viewBViewAdealloc.

mat*_*way 4

我发现这似乎是 iOS 僵尸实现中的一个错误。考虑以下代码:

#import <Foundation/Foundation.h>

@interface ClassB : NSObject
@end

@implementation ClassB
- (id)init {
    if ((self = [super init])) {
    }
    return self;
}
- (void)dealloc {
    NSLog(@"ClassB dealloc");
}
@end

@interface ClassA : NSObject
@property (nonatomic, strong) ClassB *b;
@end

@implementation ClassA
@synthesize b;
- (id)init {
    if ((self = [super init])) {
        b = [[ClassB alloc] init];
    }
    return self;
}
- (void)dealloc {
    NSLog(@"ClassA dealloc");
}
@end

int main() {
    ClassA *a = [[ClassA alloc] init];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

那应该输出:

ClassA dealloc
ClassB dealloc
Run Code Online (Sandbox Code Playgroud)

NSZombieEnabled设置为 时YES,它输出:

ClassA dealloc
Run Code Online (Sandbox Code Playgroud)

据我所知,这是一个错误。它似乎只发生在 iOS(模拟器和设备)上,而在为 Mac OS X 构建和运行时不会发生。我已经向 Apple 提交了雷达。

编辑:事实证明,这里已经回答了这个问题 - Why is object not dealloc'ed when using ARC + NSZombieEnabled。在我发现真正的问题是什么后,设法找到了它。顺便说一句,这与ARC无关。