在Objective-C中创建一个整数数组属性

63

我在Objective-C中创建整数数组属性时遇到了问题。我不确定是否能够在Obj-C中实现这个,所以希望有人能够帮助我找出正确的方法或提供替代解决方案。

myclass.h

@interface myClass : NSObject {

@private int doubleDigits[10];
}

@property int doubleDigits;
@end

myclass.m

@implementation myClass

    @synthesize doubleDigits;
    -(id) init {

        self = [super init];

        int doubleDigits[10] = {1,2,3,4,5,6,7,8,9,10};

        return self;
    }

    @end

当我构建和运行时,我会收到以下错误:

错误:属性“doubleDigits”的类型与ivar“doubleDigits”的类型不匹配


你想使用原始数组而不是NSArray有什么特别的原因吗?你应该小心,不要重新实现标准数据结构类,除非它们对你不起作用。 - user57368
1
在myclass.h文件中,@end不需要分号。另外,你应该以大写字母开头命名你的类名。 - Georg Schölly
1
@unknown(google),原因很简单,我研究了一下但是没能找到任何接近的构建方法。我尝试使用NSArray和NSNumbers,但是无法弄清楚。@gs:抱歉,那是另一个打字错误,我已经更正了。此外,我同意类名的问题;实际代码中应该是“Fraction”。 - jebcrum
7个回答

30

这应该可以工作:

@interface MyClass
{
    int _doubleDigits[10]; 
}

@property(readonly) int *doubleDigits;

@end

@implementation MyClass

- (int *)doubleDigits
{
    return _doubleDigits;
}

@end

4
补充一下,有时人们可能也想将变量赋值。在这种情况下,请使用@property(assign)和以下代码:-(void)setDoubleDigits:(int*)doubleDigits { memcpy(_doubleDigits, doubleDigits, 10*sizeof(int)); } - Ivan Vučica
4
请使用 sizeof(_doubleDigits),而不是 10 * sizeof(int)。 :( - user79758
抱歉,但这根本不起作用,你不能在@interface中声明像int这样的变量。 - Kevin

22

C 数组不是属性支持的数据类型之一。请参阅 Xcode 文档中的“Objective-C 编程语言”,在“Declared Properties”页面:

支持的数据类型

您可以为任何 Objective-C 类、Core Foundation 数据类型或“普通旧数据”(POD)类型(请参见 C++ 语言注释:POD 类型)声明属性。但是,有关使用 Core Foundation 类型的限制,请参见“Core Foundation”。

POD 不包括 C 数组。请参阅http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html

如果需要数组,则应使用 NSArray 或 NSData。

就我所见,解决方法类似于使用 (void *) 来规避类型检查。您可以这样做,但这会使您的代码难以维护。


4
引用您提供的链接上的内容:“POD类型是指C++类型的以下类别,包括这些类型的cv限定版本和这些类型的数组 [§3.9, ¶10; §9, ¶4]:标量类型,[...]”。 - Ivan Vučica

16

就像Lucius说的那样,无法拥有C数组属性。使用NSArray是正确的方法。数组只能存储对象,因此您必须使用NSNumber来存储整数。使用新的文字语法,初始化非常简单和直观:

NSArray *doubleDigits = @[ @1, @2, @3, @4, @5, @6, @7, @8, @9, @10 ];
或者:
NSMutableArray *doubleDigits = [NSMutableArray array];

for (int n = 1; n <= 10; n++)
    [doubleDigits addObject:@(n)];

获取更多信息: NSArray类参考, NSNumber类参考, Literal Syntax语法


你怎么知道这是不可能的? - Gabe

12

我只是猜测:

我认为在ivars所定义的变量会直接分配到对象中的空间。这会防止你创建访问器,因为你不能通过值将数组传递给函数,只能通过指针来传递。因此,在ivars中必须使用指针:

int *doubleDigits;

然后在init方法中为其分配空间:

@synthesize doubleDigits;

- (id)init {
    if (self = [super init]) {
        doubleDigits = malloc(sizeof(int) * 10);
        /*
         * This works, but is dangerous (forbidden) because bufferDoubleDigits
         * gets deleted at the end of -(id)init because it's on the stack:
         * int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
         * [self setDoubleDigits:bufferDoubleDigits];
         *
         * If you want to be on the safe side use memcpy() (needs #include <string.h>)
         * doubleDigits = malloc(sizeof(int) * 10);
         * int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
         * memcpy(doubleDigits, bufferDoubleDigits, sizeof(int) * 10);
         */
    }
    return self;
}

- (void)dealloc {
    free(doubleDigits);
    [super dealloc];
}

在这种情况下,接口看起来像这样:

@interface MyClass : NSObject {
    int *doubleDigits;
}
@property int *doubleDigits;

编辑:

我真的不确定是否允许这样做,那些值是否真的存在堆栈上还是存储在其他地方?它们可能存储在堆栈上,因此在这种情况下不安全使用。 (请参阅 有关初始化列表的问题)

int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
[self setDoubleDigits:bufferDoubleDigits];

这没有产生不同的结果。还有其他的想法吗? - jebcrum

6
这个有效。
@interface RGBComponents : NSObject {

    float components[8];

}

@property(readonly) float * components;

- (float *) components {
    return components;
}

1
这是正确的做法吗?还是在Objective-C中不是一种“自然”的方式? - user1280535
只读属性?我认为原帖作者也想要自动设置器。 - quantumpotato
1
@quantumpotato 这是只读的,因为您不希望更改属性指向其他内容。但是,您仍然可以更改数组元素。 - bugloaf

1
你可以把这段代码放在你的类的.h文件中,并将其定义为属性,在XCode 7中:
@property int  (*stuffILike) [10];

0

我发现之前所有的答案都太过复杂了。 我需要将一些整数数组存储为属性,并发现使用NSArray的ObjC要求是我软件中不必要的复杂化。

所以我使用了这个:

typedef struct my10ints {
    int arr[10];
} my10ints;

@interface myClasss : NSObject

@property my10ints doubleDigits;

@end

使用Xcode 6.2编译没有问题。

我的意图这样使用它:

myClass obj;
obj.doubleDigits.arr[0] = 4;

然而,这并不起作用。 它产生的结果如下:

int i = 4;
myClass obj;
obj.doubleDigits.arr[0] = i;
i = obj.doubleDigits.arr[0];
// i is now 0 !!!

使用此功能的正确方法是:

int i = 4;
myClass obj;
my10ints ints;
ints = obj.doubleDigits;
ints.arr[0] = i;
obj.doubleDigits = ints;
i = obj.doubleDigits.arr[0];
// i is now 4

因此,完全打破了我的观点(避免使用NSArray的复杂性)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接