objective-c 用nsarray初始化struct数组

我知道struct数组定义可以按如下方法进行,请问如何用一个nsarray数组来给poiCoods初始化?先谢谢各位了
CLLocationCoordinate2D poiCoords[]={{31.xxx,-117.xxx},{{31.yyy,-117.yyy}};
最新回答
词家小生

2024-07-03 02:45:56

对大大的问题不是太清晰。
猜想是问如何将struct添加到nsarray当中。
nsarray支持的是objc对象。它并不支持原生的c struct变量。
大大可以用nsvalue或者nsdata来作为struct的数据载体,将struct的地址放置在nsvalue或者nsdata当中。然后向nsarray添加。
CLLocationCoordinate2D coor;

NSValue *value;
NSArray *arr;

coor = {11.00, 22.11};
value = [NSValue valueWithPointer:&coor]; //或者 NSData data = [NSData dataWithBytesNoCopy:&coor length:sizeof(CLLocationCoordinate2D) freeWhenDone: NO];
arr = [NSArray arrayWithObject:value]; //或者 arr = @[value];

如此便能向nsarray中放置struct。

需要特别注意的是内存管理方面的问题。
NSValue并不提供对pointer的内存管理手段,所以当pointer不再被使用的时候,大大需要人工释放这些内存空间。
NSData有提供这方面的手段。但是如果没有正确管理的话,会造成出错。

举个反面的例子:
typedef struct {int n;} _s;

NSValue *func(){
NSValue *v;
_s a = {100};

v = [NSValue valueWithPointer:&a];
return v
}

int main(){
NSValue *v;
_s b;
v = func();
b = (_b)v.pointerValue
printf("%d“, b.n); //出错
}

上面的例子中,由于NSValue保存的是一个局域的变量,次变量会在func结束后自动被释放,所以func所返回的NSValue所保存的指针会失效。

正确的做法应该是:
_s *a;
a = (_s *)malloc(sizeof(_s)); //分配内存
v = [NSValue valueWithPointer:a];

使用完后:
b = v.pointerValue;
printf("%d“, b.n);

free(b); //释放内存

事实上NSData在这种情况更合适
v = [NSData dataWithBytesNoCopy:&a length:sizeof(_s) freeWhenDone: YES];
这样可以使得指针a伴随NSData v的释放而释放。
=====================

另外,也许大大问的是NSArray的创建的 short cut。
事实上
Apple LLVM Compiler 4.0 和 open-source LLVM clang v3.1对NSArray, NSDictionary 和 NSNumber 有了语法上的新支持:

NSNumber *num = @(1+3);
NSArray *arr = @[num, @"hello"];
NSDictionary *dict = @{@"num" : num};

详细倾参考资料
追问
这位朋友你好,非常抱歉没有把问题描述清楚,详情应该是一个nsarray存储了@“31.xxx,-117.xxx",@“32.xxx,-118.xxx"这样格式的坐标,请问怎样把它存到CLLocationCoordinate2D poiCoords[]这个数组里面,CLLocationCoordinate2D被定义为如下形式
struct {
CLLocationDegrees latitude;
CLLocationDegrees longitude;
} CLLocationCoordinate2D;
追答
如果大大的NSArray中是用NSString对象来储存坐标值,那我们需要做的是根据数组中的每个NSString对象的内容来转换成一对double值。因为再CLLocation.h仲 CLLocationDegrees的定义是:
typedef double CLLocationDegrees;

我们可以将这个转换用一个方程来完成:

CLLocationCoordinate2D convert(NSString *coordStr){

NSString *nstr;
NSArray *comps;
double d1, d2;
CLLocationCoordinate2D coord;

comps = [coordStr componentsSeparatedByString:@","];
nstr = [comps objectAtIndex:0];
d1 = nstr.doubleValue;
nstr = [comps objectAtIndex:1];
d2 = nstr.doubleValue;
coord.latitude = d1;
coord.longitude = d2;

return coord;
}

测试:
int main(){
@autoreleasepool {
NSArray *array;
array = @[@"31.323,-12.039", @"32.xxx,-118.xxx"];
for (NSString *str in array) {
CLLocationCoordinate2D coord;

coord = convert(str);
printf("%.3f, %.3f\n", coord.latitude, coord.longitude);
}
return 0;
}
}

打印结果:
31.323, -12.039
32.000, -118.000

又或者,可以利用CGPoint 或者CGSize的一些帮助方程来进行转换:

for (NSString *str in array) {
CGPoint p;
CLLocationCoordinate2D coord;

p = CGPointFromString([NSString stringWithFormat:@"{%@}", str]);
coord.latitude = p.x;
coord.longitude = p.y;
printf("%.3f, %.3f\n", coord.latitude, coord.longitude);
}

当然,你还要一个一个的CLLocationCoordinate2D 放进你的C 数组中。NSArray 可以用-getObjects:方法将自身的元素放入一个C数组中。但该数组的元素的类型与NSArray的元素的类型是一致的,换句话,他是一个: __unsafe_unretained NSString **

希望对你有帮助