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

时间:2014-11-27 23:55:59

标签: objective-c c

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

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

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

  1. 使用3个元素定义C struct(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)]

  4. 其中myGroceryList之前定义为     NSMutableArray * myGroceryList = [NSMutableArray array];

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

2 个答案:

答案 0 :(得分:7)

应该注意的是,我们不能将C结构放入NSArray的原因并不是因为结构有任何特殊之处。相反,我们应该将NSArray视为特殊类型的数组。

我们可以在Objective-C中将结构放在数组中。我们知道这一点,因为C程序员将结构放在数组中。

NSArray(和NSMutableArray以及所有其他NS集合对象)是一个特殊类,旨在实现专门用于Objective-C对象的数组数据结构。 NSArray仅允许Objective-C对象的事实允许NSArray执行makeObjectsPerformSelector:之类的操作。我们正在向阵列中的所有内容发送一条Objective-C消息。如果我们允许非Objective-C对象进入数组,我们就不能允许这样做。

不仅structs不允许进入NSArrayNSArray中不允许所有原始数据类型。这甚至包括NSIntegerCGFloat,因为请记住,这些是typedef'd基元 - 而不是对象。

但应注意,NSArray并不是Objective-C中唯一可用的类似数组的数据结构。请记住,Objective-C是C的严格超集。正如我已经提到的,C程序员已经将结构放入数组中。

我们总是可以使用C风格的数组。实际上,虽然它很少(由于Objective-C数组的强大功能),但我们甚至可以创建一个Objective-C对象的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 ...这看起来像一团糟。

答案 1 :(得分:3)

NSArray或NSMutableArray由对象组成。 C数据类型不是对象。因此,您无法将它们直接存储在NSArray中。

我假设你知道如何创建一个对象。在此对象中包含具有C数据类型的变量。

完成后,将该对象添加到NSArray:

NSMutableArray *yourArray = [[NSMutableArray alloc] init];

YourObject *object1 = [[YourObject alloc] init];
[yourArray addObject: object1];