2012-12-07 59 views
2

从目标C研究存储器管理所有者,我有一个关于引用计数问题:对象C - 释放物体是从其他2个对象

我有一个对象的名称obj_number。我有ALLOC它

obj_number = [[NSNumber alloc] init]; 

,然后在这个类的另一种方法(称为A),我设置

obj_number = [dataset objectAtIndex:0]; 

走出这种方法的数据集将被自动释放。我检查了这个方法后,这个方法obj_number也无法访问,也许它也是释放。

我看到一个对象是否属于一个所有权,所以如果父对象释放它也会被释放,但在我的情况下,我认为在2所有权下的obj_number(retain count可能等于2),那么为什么用尽方法A它被释放?

+0

您使用ARC吗? – trojanfoe

+0

不,如果使用ARC,我无法理解目标c的内存管理,我认为这对我的学习没有好处 –

+0

您意识到[[NSNumber alloc] init]返回nil的原因很明显吗? – FluffulousChimp

回答

0

你需要通过在.h文件提供@propertyobj_number提供setter方法,你可以做,在一个@sythesize.m文件。 setter方法将确保释放旧值并保留新值。

MyClass.h:

@interface MyClass : NSObject 
{ 
    NSNumber *_obj_number; // Use a different name for the ivar and property! 
    ... 
} 

@property (retain, nonatomic, readwrite) NSNumber *obj_number; 

... 

@end 

MyClass.m:

@implementation MyObject 
@synthesize obj_number = _obj_number; 

... 

- (void)dealloc 
{ 
    self.obj_number = nil; 
    ... 
    [super dealloc]; 
} 

和分配到obj_number的时候,你必须放弃所有权:

- (void)someMethod 
{ 
    // We own myNumber, so release 
    NSNumber *myNumber = [[NSNumber alloc] initWithUnsigned:12]; 
    self.obj_number = myNumber; 
    [myNumber release]; 

    // However this is easier: 
    self.obj_number = [NSNumber numberWithUnsigned:12]; 
} 

- (void)someOtherMethod 
{ 
    // We don't own [dataset objectAtIndex:0] so no need to release 
    self.obj_number = [dataset objectAtIndex:0]; 
} 
+0

所以在行后面self.obj_number = [dataset objectAtIndex:0];属性obj_number不会被释放,对吗?我在setter方法中看到,参数被保留,意味着[dataset objectAtIndex:0]被保留。我对吗? –

+0

@ pf2707是的,那是对的。 – trojanfoe

+0

谢谢,我有很多要学习的目标c。 :D –

1

编辑:你使用非ARC?

在方法,你可能有这样的:

-(void)A{ 
    .... 
    obj_number = [dataset objectAtIndex:0]; 
    [dataset autorelease]; 
} 

在上面要更改obj_number的指针指向[dataset objectAtIndex:0]

根据你under 2 ownership (retain count may equals to 2)

我希望你的内涵将copyretain此值,对不对?

然后你可以使用obj_number = [[dataset objectAtIndex:0] copy];//or retain只有其保持数将增加至2

+0

非ARC = MRR“手动保持释放” – trojanfoe

+0

啊,是的,我明白了。也许我误解了这里的一些事情。非常感谢。 :D –

+1

感谢你的提醒@pierre,我忘了这么做。 :D –

0

你不应该认为保持计数。重要的是所有权。

obj_number = [[NSNumber alloc] init]; 

创建您拥有的新的NSNumber实例。这意味着你不得不在不再需要的时候释放它。

obj_number = [dataset objectAtIndex:0]; 

这给你一个你不拥有的物体。你不必释放它。如果您想拥有所有权,则必须向其发送保留消息,并且必须稍后再发布。

您的代码的另一点。如果你写这样的东西你有内存泄漏(如果你不使用ARC):

//obj_number = [[NSNumber alloc] init]; // returns nil, so no leak 
obj_number = [[NSNumber alloc] initWithInt:1]; 
some code // No [obj_number release] or [obj_number autorelease] here 
obj_number = [dataset objectAtIndex:0]; 

最后一行导致泄漏。在该行之后,obj_number指向数据集中索引为0的对象,而不再是您在开始处分配的NSNumber。

编辑: 就像trojanfoe说的那样,在大多数情况下,最好使用属性,因为他们为你做内存管理。

+0

实际上,在写的例子中,最后一行不会导致泄漏,因为[[[NSNumber alloc] init]'返回nil;但是如果使用合适的初始化工具,它将会泄漏。 – FluffulousChimp

+0

你是对的,我改变了代码,以便它会泄漏,并符合我的解释 – Pierre

+0

所以我想在行obj_number = [dataset objectAtIndex:0]; obj_number不在我的所有权了,对吧?在此范围之后,它将作为数据集 –