Fat*_*tie 84 iphone cocoa struct objective-c nsarray
存储c结构的常用方法是NSArray什么?优点,缺点,内存处理?
值得注意的是,有什么之间的区别valueWithBytes和valueWithPointer -由Justin和鲶鱼下面提出.
这是 Apple valueWithBytes:objCType:对未来读者讨论的链接 ......
对于一些横向思考和更多关注性能,Evgen提出了STL::vector在C++中使用的问题.
(这引发了一个有趣的问题:是否有一个快速的c库,不是STL::vector很轻,但更轻,允许最小的"整理数组处理"......?)
那么原来的问题......
例如:
typedef struct _Megapoint {
float w,x,y,z;
} Megapoint;
Run Code Online (Sandbox Code Playgroud)
那么:在一个NSArray成语中存储一个人自己的结构的正常,最好,惯用的方式是什么?你如何处理那个成语中的记忆?
请注意,我特意寻找存储结构的通常习惯用法.当然,人们可以通过创建一个新的小班来避免这个问题.但是,我想知道实际将结构放入数组的常用习惯,谢谢.
顺便说一句,这可能是NSData的方法吗?不是最好的......
Megapoint p;
NSArray *a = [NSArray arrayWithObjects:
[NSData dataWithBytes:&p length:sizeof(Megapoint)],
[NSData dataWithBytes:&p length:sizeof(Megapoint)],
[NSData dataWithBytes:&p length:sizeof(Megapoint)],
nil];
Run Code Online (Sandbox Code Playgroud)
BTW作为参考点,感谢Jarret Hardie,以下是如何存储CGPoints和类似的NSArray:
NSArray *points = [NSArray arrayWithObjects:
[NSValue valueWithCGPoint:CGPointMake(6.9, 6.9)],
[NSValue valueWithCGPoint:CGPointMake(6.9, 6.9)],
nil];
Run Code Online (Sandbox Code Playgroud)
Jus*_*ers 154
NSValue不仅支持CoreGraphics结构 - 您也可以使用它.我建议这样做,因为类可能比NSData简单的数据结构更轻.
只需使用如下表达式:
[NSValue valueWithBytes:&p objCType:@encode(Megapoint)];
Run Code Online (Sandbox Code Playgroud)
并获得价值:
Megapoint p;
[value getValue:&p];
Run Code Online (Sandbox Code Playgroud)
我建议你坚持这NSValue条路线,但是如果你真的希望struct在你的NSArray(以及Cocoa中的其他集合对象)中存储普通的'ol 数据类型' ,你可以这样做 - 虽然是间接的,使用Core Foundation和免费桥接.
CFArrayRef(及其可变对应物CFMutableArrayRef)在创建数组对象时为开发人员提供了更大的灵活性.请参阅指定初始化程序的第四个参数:
CFArrayRef CFArrayCreate (
CFAllocatorRef allocator,
const void **values,
CFIndex numValues,
const CFArrayCallBacks *callBacks
);
Run Code Online (Sandbox Code Playgroud)
这允许您请求CFArrayRef对象使用Core Foundation的内存管理例程,根本不使用甚至是您自己的内存管理例程.
必要的例子:
// One would pass &kCFTypeArrayCallBacks (in lieu of NULL) if using CF types.
CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
NSMutableArray *array = (NSMutableArray *)arrayRef;
struct {int member;} myStruct = {.member = 42};
// Casting to "id" to avoid compiler warning
[array addObject:(id)&myStruct];
// Hurray!
struct {int member;} *mySameStruct = [array objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)
上面的例子完全忽略了内存管理方面的问题.结构myStruct在堆栈上创建,因此在函数结束时被销毁 - 数组将包含指向不再存在的对象的指针.您可以通过使用自己的内存管理例程来解决这个问题 - 因此为什么提供选项 - 但是您必须进行引用计数,分配内存,解除分配等等的艰苦工作.
我不推荐这个解决方案,但会保留在这里以防其他人感兴趣.:-)
使用在堆上分配的结构(代替堆栈)在此处演示:
typedef struct {
float w, x, y, z;
} Megapoint;
// One would pass &kCFTypeArrayCallBacks (in lieu of NULL) if using CF types.
CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
NSMutableArray *array = (NSMutableArray *)arrayRef;
Megapoint *myPoint = malloc(sizeof(Megapoint);
myPoint->w = 42.0f;
// set ivars as desired..
// Casting to "id" to avoid compiler warning
[array addObject:(id)myPoint];
// Hurray!
Megapoint *mySamePoint = [array objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)