1

苹果文档NSData

NSData及其可变子类NSMutableData为字节缓冲区提供数据对象、面向对象的包装器。数据对象让简单分配的缓冲区(即没有嵌入指针的数据)具有 Foundation 对象的行为。

“嵌入式指针”是什么意思?我的理解是,一旦您将字节放入其中,除非您在应用程序级别对其进行解码,否则它不知道它是什么。有人知道他们在说什么吗?

4

2 回答 2

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)];
于 2012-09-09T23:44:23.667 回答
1

是的,这就是他们所说的。NSData 是纯序列化数据,一个字节数组。任何结构都必须在应用程序代码中添加,并且对外部内存的引用没有多大意义(NSData 等数据对象应该是自包含的,或者至少以不依赖于确切内存位置的方式引用事物,所以它是可运输的)。他们只是想清楚这一点。

于 2012-09-09T23:28:36.743 回答