2012-01-01 94 views
0

當第二個對象被釋放時,第二個對象中創建的對象不會被解除分配,除非我在dealloc中將指針設置爲nil,這看起來不正確。ARC下的對象沒有被刪除

我以爲ARC應該設置所有指針爲零,默認情況下,當對象被釋放時,從而釋放任何擁有的對象。

這裏是我的代碼(只是去核):

@interface Obj1 : NSObject 
{ 
    Obj2 *obj2; 
} 

@interface Obj2 : NSObject 
{ 
} 

@implementation Obj1 

-(void)dealloc 
{ 
    obj2 = nil; // <--- This is needed to get obj2 to be dealloc'd. 
    NSLog(@"Obj1 dealloc"); 
} 

-(id)init 
{ 
    if ((self = [super init]) == nil) 
     return nil; 

    obj2 = [[Obj2 alloc] init]; 

    return self; 
} 

@end 

@implementation Obj2 

-(void)dealloc 
{ 
    NSLog(@"Obj2 dealloc"); 
} 

-(id)init 
{ 
    if ((self = [super init]) == nil) 
     return nil; 

    return self; 
} 

@end 

我做錯什麼了嗎?我讀過的所有內容都說這應該起作用。沒有其他人持有obj2,因爲將其設置爲零釋放它。我已經嘗試過使用和不使用dealloc函數的代碼,以防萬一它搞砸了某些東西,我也得到了相同的結果。

有問題的文件正在編譯爲obj-C++,但我沒有對C++和對象做任何事情。

謝謝。

+0

OK ,我發現了這個問題。我有啓用殭屍對象設置。我感到驚訝的是,如果它不被設置爲零,保持對象不被刪除。我認爲Zombie Objects在被刪除後就被置於對象的位置。如果它從未調用dealloc,那可能會導致一些其他更大的問題。 – 2012-01-02 00:09:10

回答

1

這應該可以按照您期望的方式工作。您可能在代碼中偶然做了一些事情,這些代碼是從您的示例中混淆或刪除的。爲了演示,您可以將下面的代碼保存到某個文件中,例如arc_tst.m,編譯並從終端運行它。您會看到它會打印出所有預期的日誌語句,然後通過釋放這兩個對象來結束。這些對象與您在此處發佈的示例代碼中的模型完全相同(證明問題很可能在您的實際代碼的其他部分中)。

要編譯它,假設你已經把它命名爲arc_tst.m,更改爲文件保存的目錄,然後輸入以下內容:

$ clang -fobjc-arc -o arc_tst arc_tst.m -framework foundation 
$ ./arc_tst 

arc_tst.m

// build with: clang -fobjc-arc -o arc_tst arc_tst.m -framework foundation 

#import <Foundation/Foundation.h> 

@class Obj1, Obj2; 

@interface Obj1 : NSObject 
{ 
    Obj2* _obj2; 
} 

@end 

@interface Obj2 : NSObject 
{ 
} 

@end 

@implementation Obj1 

- (id)init 
{ 
    if((self = [super init])) 
    { 
    _obj2 = [[Obj2 alloc] init]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    NSLog(@"Obj1 Dealloc"); 
} 

@end 

@implementation Obj2 

- (id)init 
{ 
    if((self = [super init])) 
    { 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    NSLog(@"Obj2 Dealloc"); 
} 

@end 

int main (int argc, char const *argv[]) 
{ 
@autoreleasepool { 
    Obj1* obj = [[Obj1 alloc] init]; 
    NSLog(@"after alloc, have obj1: %@", obj); 
    sleep(2); 
    NSLog(@"after sleep, have obj1: %@", obj); 
    obj = nil; // force ARC to trash obj 
    NSLog(@"after nil on obj1, about to exit"); 
} 
return 0; 
} 
+0

您的代碼示例如您所描述的那樣工作。我只是無法弄清楚我在我的代碼中做了什麼。我的Obj1正在被解除分配,但Obj2不是除非我將它設置爲零。我正在編譯我的代碼爲obj-C++,我不知道這是否會有所作爲。 – 2012-01-01 22:53:43

+0

@RogerGilbrat嗯......這可能會有所作爲。我在問題中添加了標籤,但您可能想要更新您的問題,以更準確地說明您如何使用此代碼以及它如何與C++代碼交互。 – 2012-01-01 23:02:36

+0

它根本不與C++代碼交互。我唯一使用C++的是能夠重載基於param類型的純c函數。而已。未被刪除的對象與C++無關。所有這些都是純粹的obj-c。 – 2012-01-01 23:05:17