创建仅包含给定类的对象的数组

时间:2009-07-13 18:39:54

标签: objective-c generics collections strong-typing

好的,所以我有下面的代码(Objective-C FYI),我想知道是否要创建一个c_data对象的NSMutableArray,我该怎么做呢?这有点像在C#中声明 List<c_data> cData

@interface c_data : NSObject {
    double value;
    int label;
    int ID;
}    
@property double value;
@property int label;
@property int ID;

-(c_data*) init;
-(c_data*) initWithValue:(double)value;    
@end

@implementation c_data
@synthesize value, label, ID;
-(c_data*) init {
    return self;
}
-(c_data*) initWithValue:(double)val {
    value = val;
    return self;
}
@end

如果您查看课程feat_data,我正在尝试将cData作为课程c_data的数组。我已将尝试包括在内,但我不认为这是正确的,因为c_data不是数组。有什么建议?

@interface feat_data : NSObject {
    NSMutableArray *nData;
    NSMutableArray *cData;
    char type;
}
@property(nonatomic, retain) NSMutableArray *nData;
@property(nonatomic, retain) NSMutableArray *cData;
@property char type;
-(feat_data*)init;
@end

@implementation feat_data
@synthesize nData, cData, type;
-(feat_data*)init {
    nData = [[NSMutableArray alloc] init];
    c_data *c_dataInstance = [[c_data alloc] init];
    cData = [[NSMutableArray alloc] initWithArray:c_dataInstance];
    return self;
}
@end

3 个答案:

答案 0 :(得分:3)

Objective-C中没有静态类型/模板/泛型集合。基本上,强类型集合的要点是在编译时提供静态类型安全性。这种方法在一种像Objective-C这样动态的语言中毫无意义。 Objective-C集合中不同对象类型问题的解决方法是仅插入适当的对象类型。 (另外,请记住,数组将保留它包含的对象,因此,如果插入新对象而不释放,并且丢失指向它的指针,则会泄漏内存。)

如果你考虑一下,泛型的最大好处之一就是能够将集合中的对象直接检索到静态类型的变量而不需要强制转换。在Objective-C中,您可以只存储到id变量并发送您喜欢的任何消息而不必担心ClassCastException,或者编译器抱怨对象没有(可能不是?)实现您所使用的方法试图调用。如果需要,您仍然可以静态输入变量并投射结果,但更简单的方法是使用动态类型(如果需要,还可以-isKindOfClass:-respondsToSelector:。)

顺便提一下,Stack Overflow上有几个相关的问题。知道要搜索的术语(“通用”,“强类型”或“模板”)可以帮助找到它们。以下是一些:

最后,我同意William的观点 - 您提供的示例中的init方法非常令人震惊。你最好在Objective-C中学习并注意Apple的Allocating and Initializing Objects规则。它需要来自其他语言的破坏习惯,但它会在未来的某个时刻为您节省无数个小时的精神错乱。 : - )

答案 1 :(得分:2)

您将创建一个NSMutableArray并将c_data个对象插入其中。

答案 2 :(得分:2)

[NSMutableArray addObject:[[[c_data alloc] init] autorelease]];

没有输入Objective-C数组。看起来你有一些C ++无法学习。

在相关的说明中,你的内容非常糟糕。你也需要调用super init,因为:

- (id)init {
  self = [super init];
  if (self != nil) {
    //Initialize here.
  }
  return self;
}