2012-01-24 29 views
5

thể trùng lặp:
Why is object not dealloc'ed when using ARC + NSZombieEnabledStrange ARC vấn đề không giải phóng Ivar trong UIView lớp con

Tôi đã có một vấn đề rất lạ tôi nhìn thấy tại thời điểm trong một dự án. Nói một cách đơn giản, tôi có ViewA sở hữu ViewB (thuộc tính strong). ViewA tạo ViewB trong trình khởi tạo của nó. Cả hai đối tượng là các lớp con của UIView.

Tôi đã ghi đè dealloc trong cả hai và đặt dòng nhật ký và điểm ngắt để xem liệu chúng có bị trúng hay không. Có vẻ như số dealloc của ViewA đang bị ảnh hưởng nhưng không phải là số ViewB. Tuy nhiên, nếu tôi đặt trong một số self.viewB = nil trong số dealloc của ViewA thì nó .

Vì vậy, về cơ bản nó là một cái gì đó như thế này:

@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 

Những gì tôi không thể hiểu là tại sao con số không-ing viewB ra làm cho một sự khác biệt. Nếu một cái gì đó khác đang nắm giữ vào viewB thì nó sẽ làm cho hoàn toàn không có sự khác biệt nếu tôi nil nó ra hay không ở đây. Và nó cũng không tạo nên sự khác biệt với số lượng bản phát hành mà ARC thêm vào.

Tôi dường như không thể tái tạo nó trong một trường hợp thử nghiệm tối thiểu, nhưng tôi đang nghiên cứu nó. Và tôi không thể đăng mã thực sự mà tôi thấy điều này thật không may. Tôi không thấy rằng đó là một vấn đề mặc dù bởi vì nó là nhiều điểm mà nil-ing nó ra không nên tạo sự khác biệt mà tôi đang bối rối bởi.

Có ai có thể nhìn thấy bất cứ điều gì tôi đang xem hoặc đưa ra lời khuyên về nơi để tìm cách gỡ rối vấn đề này không?

Cập nhật:

tôi đã tìm thấy vấn đề. Có vẻ như đó chỉ là vấn đề khi NSZombieEnabled được đặt thành YES. Vâng, đó là hoàn toàn điên rồ và phải là một lỗi chắc chắn. Zombies không nên ảnh hưởng đến cách làm việc này theo như tôi biết. Các đối tượng vẫn phải đi qua phương pháp dealloc. Và những gì nhiều hơn, nó chỉ điên mà nó hoạt động nếu tôi nil ra viewB trong ViewA 's dealloc.

+0

Là một chủ đề ngoài, bạn có thể làm cho nó yếu và quên vấn đề: '[self addSubview: self.viewB]' giữ lại 'viewB' cho bạn, vì vậy nó sẽ không được phát hành sớm ngay cả khi bạn giữ một tham chiếu 'yếu' với nó. – dasblinkenlight

+0

Trừ khi anh ấy cần chạy trên iOS 4.3. –

+0

Chính xác. Tôi muốn nó chạy trên iOS 4.x và cũng có thể, tôi ** không cần phải làm điều đó **. Tôi không hiểu tại sao nil-ing 'viewB' trong' dealloc' lại tạo sự khác biệt. Điều đó dường như điên với tôi. – mattjgalloway

Trả lời

4

Tôi đã nhận thấy rằng đây dường như là lỗi trong việc triển khai zombie của iOS. Xét đoạn mã sau:

#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; 
} 

Đó nên đầu ra:

ClassA dealloc 
ClassB dealloc 

Nhưng với NSZombieEnabled thiết lập để YES, nó kết quả đầu ra:

ClassA dealloc 

Theo như tôi có thể nói, đây là một lỗi. Dường như chỉ xảy ra với iOS (cả trình mô phỏng và thiết bị) và không xảy ra khi được xây dựng và chạy cho Mac OS X. Tôi đã gửi một radar với Apple.

Chỉnh sửa: Nó chỉ ra điều này đã được trả lời ở đây - Why is object not dealloc'ed when using ARC + NSZombieEnabled. Quản lý để tìm nó sau khi tôi phát hiện ra vấn đề thực sự là gì. Đó là không có gì để làm với ARC bằng cách này.

+0

offtopic: không có [super dealloc]; cuộc gọi? – CarlJ

+1

@meccan - Không, vì tôi đang sử dụng ARC. – mattjgalloway

Các vấn đề liên quan