为什么我们不能直接在NSArray中存储C结构

Sma*_*ome 1 c objective-c

当我试图将C结构存储到NSArray时,我遇到了一个错误(我能够通过转换为NSData来解决它,如下面链接中所指定的).但是,我很想知道为什么没有使用NSData的麻烦就行不通. 链接到我使用的解决方案

请注意:我不想要解决方案,它已经解决了.我只是想通过理解为什么下面的直接方法不起作用来提高我对Objective-C基础的理解.

我想做的事情:一个简单的程序,允许一个人添加一个杂货项目,并在添加到购物车后将其标记为已完成

  1. 使用3个元素定义C结构(item,count和BOOL的名称,以跟踪它是否已添加到购物车)

  2. 每次创建新项目时,我都会执行以下groceryItem*secondGroceryItem = malloc(sizeof(groceryItem)); secondGroceryItem-> itemName ="Beer"; secondGroceryItem-> count = 3; secondGroceryItem-> purchase = NO;

  3. 然后我将它添加到NSMutableArray使用[myGroceryList addObject:(__ bridge id)(secondGroceryItem)]跟踪杂货项目

其中myGroceryList早先定义为NSMutableArray*myGroceryList = [NSMutableArray array];

这不起作用.我必须在存储在NSMutableArray之前转换为NSData.为什么我不能直接在NSMutableArray中存储指向我的C结构的指针?

nhg*_*rif 8

应该指出的是,我们不能将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]);
}
Run Code Online (Sandbox Code Playgroud)

这将编译,运行并完全符合您在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);
}
Run Code Online (Sandbox Code Playgroud)

同样,这是完全有效的Objective-C代码.

你必须问自己的问题:拥有一个结构并处理一个C风格的数组是否更好,或者我的结构能否更好地作为一个我可以放入的对象NSArray?我不会使用struct我转换NSData回来的东西只是为了把它变成一个NSArray......这看起来像一团糟.