2012-12-07 53 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不在我的所有權了,對吧?在此範圍之後,它將作爲數據集 –