【问题标题】:Create an array of integers property in Objective-C在 Objective-C 中创建一个整数属性数组
【发布时间】:2010-10-03 08:58:27
【问题描述】:

我在 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 的类型不匹配 '双位数'

【问题讨论】:

  • 有什么特别的原因要使用原始数组而不是 NSArray?您应该小心,不要最终重新实现标准数据结构类,除非它们不适合您。
  • @end(在 myclass.h 中)不需要分号。你也应该以大写字母开头你的类名。
  • @unknown(google),原因只是我调查了它,但没有得到任何可以构建的东西。我尝试了一个 NSNumber 的 NSArray,但无法弄清楚。 @gs:抱歉,这是我更正的另一个错字。另外,我同意班级名称;它实际上是真实代码中的“分数”。

标签: objective-c arrays properties


【解决方案1】:

我只是推测:

我认为 ivars 中定义的变量在对象中分配空间。这可以防止您创建访问器,因为您不能按值将数组提供给函数,而只能通过指针。因此,您必须在 ivars 中使用指针:

int *doubleDigits;

然后在init-method中为它分配空间:

@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;

编辑:

我真的不确定是否允许这样做,这些值是真的在堆栈上还是存储在其他地方?它们可能存储在堆栈中,因此在这种情况下使用不安全。 (见question on initializer lists

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

【讨论】:

  • 这并没有产生不同的结果。还有其他想法吗?
【解决方案2】:

这应该可行:

@interface MyClass
{
    int _doubleDigits[10]; 
}

@property(readonly) int *doubleDigits;

@end

@implementation MyClass

- (int *)doubleDigits
{
    return _doubleDigits;
}

@end

【讨论】:

  • 只是为了补充这一点,可能还想分配给变量。在这种情况下,使用@property(assign) 和:-(void)setDoubleDigits:(int*)doubleDigits { memcpy(_doubleDigits, doubleDigits, 10*sizeof(int)); }
  • sizeof(_doubleDigits),不是10 * sizeof(int),拜托。 :(
  • 对不起,这根本不起作用,你不能在@interface中声明像int这样的变量。
【解决方案3】:

这行得通

@interface RGBComponents : NSObject {

    float components[8];

}

@property(readonly) float * components;

- (float *) components {
    return components;
}

【讨论】:

  • 这是正确的做法吗?或者这不是目标 c 中的“自然”方式?
  • 只读?我认为 OP 也希望有自动设置器。
  • @quantumpotato 它是只读的,因为您不想将属性更改为指向其他内容。不过,您仍然可以更改数组元素。
【解决方案4】:

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

支持的类型

您可以为任何 Objective-C 类,核心基础 数据类型,或“普通旧数据”(POD) 类型(参见 C++ 语言注释:POD 类型)。对于使用 Core 的限制 然而,基础类型,请参阅“核心 基金会。”

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

如果你需要一个数组,你应该使用 NSArray 或 NSData。

在我看来,解决方法就像使用 (void *) 来规避类型检查。你可以这样做,但它会降低你的代码的可维护性。

【讨论】:

  • 从您的链接中引用:“POD 类型一词统指以下类别的 C++ 类型,包括这些类型的 cv 限定版本以及这些类型的 数组 [§3.9, ¶10; §9, ¶4]: 标量类型, [...]".
【解决方案5】:

就像 lucius 所说,不可能有 C 数组属性。使用NSArray 是可行的方法。数组只存储对象,所以你必须使用NSNumbers 来存储你的整数。使用新的文字语法,初始化它非常简单直接:

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 Class ReferenceNSNumber Class ReferenceLiteral Syntax

【讨论】:

  • 你怎么知道不可能?
【解决方案6】:

我发现所有以前的答案都太复杂了。 我需要将一些整数数组存储为属性,并发现使用 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 的复杂性)。

【讨论】:

    【解决方案7】:

    您可以将它放在您的类的 .h 文件中,并将其定义为属性,在 XCode 7 中:

    @property int  (*stuffILike) [10];
    

    【讨论】:

      猜你喜欢
      • 2013-05-17
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 2019-05-22
      • 2011-10-01
      相关资源
      最近更新 更多