2009-06-02 11 views
2

我正在與AsyncSocket其中所述AsyncSocket對象調用時,它從遠端接收數據低於委託方法工作:現在NSString stringWithCString:length:保留我傳入的字節數組?

- (void)onSocket:(AsyncSocket*)socket didReadData:(NSData*)data withTag:(long)tag; 

,在此方法中,我通過NSData對象到以下命令中來獲得的數據的的NSString表示接收:

NSString *body = [NSString stringWithCString:[data bytes] length:[data length]; 

確實的NSString stringWithCString:長度:保留字節數組我通過在?我需要保留NSData *數據嗎?我需要在最後釋放NSString * body嗎?

謝謝。我想根據代表方法獲得內存管理...

回答

2

是否NSString stringWithCString:length:保留我傳入的字節數組?

不可能保留一個字節數組。只有對象可以保留。

我需要保留NSData *數據嗎?

不可以。因爲字符串沒有辦法保留數據(它不知道的)或其內容,字符串將複製字節。 (想想如果你正在實施這種方法,你會怎麼做:這就是它。)

讓我們來改變個案,看看如果你傳遞數據對象而不是字節,你會做什麼。

如果字符串確實保留了數據,那麼您不需要擔心字符串下的數據將被刪除,因爲字符串正在保留它。如果它不保留它,那麼該字符串要麼是自己的副本,要麼根本就沒有保存你的數據。

所以其他物體的保留並不重要。不要擔心他們。只擔心誰擁有什麼,並保留或不保留。

我是否需要在最後釋放NSString * body?

那麼,你沒有保留它,你沒有分配它,你沒有複製它。因此,你不擁有它。所以不行。

如果您確實想要取得對象的所有權,您可以保留它或製作(然後擁有)您自己的副本。然後你會釋放它。

0

您不必保留NSData數組,因爲它的內容將被轉換/複製到新的NSString對象中。

返回的NSString對象的保留計數爲1,但它已被添加到autorelease池中。
這意味着一旦autorelease池被銷燬它就會自動釋放。如果你正在使用由AppKit創建的默認自動釋放池,這將發生在當前事件循環處理結束時。因此,如果僅在該方法中使用此字符串對象「onsocket:...」,那麼您很好。

如果你想保留的NSString對象留下您應該保留它或通過分配和初始化像這樣初始化它的方法後:
[[的NSString頁頭] initWithBytes:[...]長:[。 ..]編碼:[...]]
此NSString對象的保留計數爲1,但在不再需要時必須將其明確釋放。

Btw。 [NSString stringWithCString:length:]已棄用,因爲OSX 10.4

0

Pholker是正確的;您應該使用stringWithCString:encoding:來代替。

只有對象需要保留/釋放;因爲你正在傳遞一個C字符串(它不是一個對象,不像NSString),所以沒有什麼可以保留或釋放。

由於您使用的是便捷構造 NSString的具有1的保留計數,但被添加到自動釋放池,所以在某些時候你離開代碼塊後,這將被釋放。你不需要明確地使用alloc和init方法來保留它。我的意思是,它的保留計數爲1(但會被自動釋放)。如果你在其上調用保留,它會將計數增加到2,但是在一段時間後,它會自動恢復,並且保留計數將下降爲1.

如果您不對對象調用init,retain,copy或mutableCopy,則可以假定它將被自動釋放,並且不需要顯式釋放任何東西。但是如果你想保持一個代碼塊外的對象,你需要調用retain並在一段時間後釋放它(通常在創建對象的類的dealloc方法中)。

1

簡單的答案與證明。 NSString stringWithCString:encoding:複製字節緩衝區以生成字符串。緩衝區由您來維護。

證明:

代碼:

const char* hardString = "Hello, World"; 
    char *buffer = nil; 

    buffer = calloc(13, 1); 
    bzero(buffer, 13); 

    memcpy(buffer, hardString, 12); 

    NSString *aString = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];   
    NSLog(@"aString: %@ \t filled buffer:(%p) [%s]", aString, (void*)buffer, buffer); 

    bzero(buffer, 13); 
    NSLog(@"aString: %@ \t zeroed buffer:(%p) [%s]", aString, (void*)buffer, buffer); 

    free(buffer); 
    NSLog(@"aString: %@ \t free'd buffer:(%p)", aString, (void*)buffer); 

    buffer = nil;   
    NSLog(@"aString: %@ \t nulled buffer:(%p)", aString, (void*)buffer); 

結果:

aString: Hello, World filled buffer:(0x10010a790) [Hello, World] 
aString: Hello, World zeroed buffer:(0x10010a790) [] 
aString: Hello, World free'd buffer:(0x10010a790) 
aString: Hello, World nulled buffer:(0x0)