2012-01-01 133 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

相关问题