当我试图将C结构存储到NSArray时,我遇到了一个错误(我能够通过转换为NSData来解决它,如下面链接中所指定的).但是,我很想知道为什么没有使用NSData的麻烦就行不通. 链接到我使用的解决方案
请注意:我不想要解决方案,它已经解决了.我只是想通过理解为什么下面的直接方法不起作用来提高我对Objective-C基础的理解.
我想做的事情:一个简单的程序,允许一个人添加一个杂货项目,并在添加到购物车后将其标记为已完成
使用3个元素定义C结构(item,count和BOOL的名称,以跟踪它是否已添加到购物车)
每次创建新项目时,我都会执行以下groceryItem*secondGroceryItem = malloc(sizeof(groceryItem)); secondGroceryItem-> itemName ="Beer"; secondGroceryItem-> count = 3; secondGroceryItem-> purchase = NO;
然后我将它添加到NSMutableArray使用[myGroceryList addObject:(__ bridge id)(secondGroceryItem)]跟踪杂货项目
其中myGroceryList早先定义为NSMutableArray*myGroceryList = [NSMutableArray array];
这不起作用.我必须在存储在NSMutableArray之前转换为NSData.为什么我不能直接在NSMutableArray中存储指向我的C结构的指针?
应该指出的是,我们不能将C结构放入的NSArray
原因并不是因为结构的任何特殊之处.相反,我们应该考虑NSArray
成为一种特殊类型的数组.
我们可以在Objective-C中将结构放在数组中.我们知道这是因为C程序员将结构放在数组中.
NSArray
(以及NSMutableArray
所有其他NS
集合对象)是一个特殊类,旨在实现专门用于Objective-C对象的数组数据结构.NSArray
只允许Objective-C对象的事实允许NSArray
做类似的事情makeObjectsPerformSelector:
.我们正在向阵列中的所有内容发送一条Objective-C消息.如果我们允许非Objective-C对象进入数组,我们就不能允许这样做.
这不仅仅是structs
不被允许进入的NSArray
.a中不允许所有原始数据类型NSArray
.这甚至包括,NSInteger
并且CGFloat
因为记住,这些是typedef的原语 - 而不是对象.
然而,应该注意,这NSArray
不是Objective-C中我们可用的唯一类似数组的数据结构.请记住,Objective-C是C的严格超集.正如我已经提到的,C程序员已经将结构放入数组中.
我们总是可以使用C风格的数组.实际上,尽管很少(由于Objective-C数组的强大功能),我们甚至可以创建一个C-style的Objective-C对象数组.
考虑:
NSString *stringArray[3]; stringArray[0] = @"foo"; stringArray[1] = @"bar"; stringArray[2] = @"baz"; for (int i = 0; i < 3; ++i) { NSLog(@"%@", stringArray[i]); }
这将编译,运行并完全符合您在Objective-C中的期望.因此,我们可以完全相同的struct
:
typedef struct Foo { int x; int y; } Foo; Foo fooArray[3]; fooArray[0] = (Foo){.x = 1, .y = 2}; fooArray[1] = (Foo){.x = 3, .y = 4}; fooArray[2] = (Foo){.x = 5, .y = 6}; for (int i = 0; i < 3; ++i) { NSLog(@"Foo(x: %i, y: %i)", fooArray[i].x, fooArray[i].y); }
同样,这是完全有效的Objective-C代码.
你必须问自己的问题:拥有一个结构并处理一个C风格的数组是否更好,或者我的结构能否更好地作为一个我可以放入的对象NSArray
?我不会使用struct
我转换NSData
回来的东西只是为了把它变成一个NSArray
......这看起来像一团糟.