2012-09-09 42 views
1

關於NSData蘋果的文件說的NSData和嵌入式指針澄清

NSData及其可變子類NSMutableData爲字節的緩衝區提供的數據對象,面向對象的封裝。數據對象讓簡單分配的緩衝區(即沒有嵌入式指針的數據)承擔基礎對象的行爲。

他們是什麼意思的「嵌入式指針」?我的理解是,一旦將字節放入其中,它就不知道它是什麼,除非您在應用程序級別解碼它。任何人都知道他們在說什麼?

回答

5

NSData的目的是提供一種方法來清理不再需要的分配數據緩衝區,即當NSData的引用計數變爲0時。在常見情況下,數據分配爲malloc和NSData使用相應的調用來釋放數據。這限制了字節數據的性質。它必須是普通的舊數據。如果數據是一個包含指向使用malloc(嵌入指針)分配的另一個內存區域的字段的結構,則嵌入的指針永遠不會被NSData對象釋放,從而導致內存泄漏。例如:

typedef struct Point { 
    CGFloat x, 
    CGFloat y 
} Point; 

typedef struct LineSegment { 
    Point* start; 
    Point* end; 
} LineSegment; 

// point does not contain any embedded pointers (i.e., it is Plain Old Data) 
Point* point = malloc(sizeof(Point)); 
// pointData will call free on point to deallocate the memory allocated by malloc 
NSData* pointData = [NSData dataWithBytesNoCopy:point length:sizeof(Point)]; 

Point* start = malloc(sizeof(Point)); 
Point* end = malloc(sizeof(Point)); 

// line contains two embedded pointers to start and end. Calling free on line 
// without calling free on start and end will leak start and end 
LineSegment* line = malloc(sizeof(LineSegment)); 
line->start = start; 
line->end = end; 

// start and end will be leaked! 
NSData* lineData = [NSData dataWithBytesNoCopy:&line length:sizeof(LineSegment)]; 

// Try this instead. Line is now Plain Old Data 
typedef struct Line { 
    Point start; 
    Point end; 
} Line; 

// anotherLine does not contain any embedded pointers and can safely be used with 
// NSData. A single call to free will deallocate all memory allocated for anotherLine 
// with malloc 
Line* anotherLine = malloc(sizeof(Line)); 

NSData* anotherLineData = [NSData dataWithBytesNoCopy:&anotherLine 
               length:sizeof(Line)]; 
+0

非常有幫助的響應。現在我明白了,再加上與Thilo不同的層次!我也想感謝Thilo,因爲這是一個很好的迴應。 – mskw

1

是的,這就是他們正在談論的內容。 NSData是純串行數據,是一個字節數組。任何結構都必須添加到應用程序代碼中,並且對外部內存的引用沒有太大意義(數據對象(如NSData)應該是自包含的,或者至少以不依賴於確切內存位置的方式引用),所以它是可運輸的)。他們只是想清楚它。