如何动态定义实例变量?

时间:2010-04-25 15:09:35

标签: objective-c

我有两个类(class1和class2)只存储数据,没有方法。我有一个第三个类,它有一个实例变量,根据一些用户输入,它将被设置为两个类中的一个。因此,在第三类中,我将变量一般声明为

NSObject *aClass;

并在运行时将其设置为它应该是什么。

aClass = [[Class1 alloc] init]; // or 
aClass = [[Class2 alloc] init];

但是,当我尝试从aClass

访问字段时
NSString *str = aClass.field1;

它给了我错误:在某个结构或联合的东西中请求成员'field1'。 Field1在class1和class2中声明。当我尝试施放aClass

aClass = (Class1 *) aClass;

它给出了同样的错误。我做错了什么,有更好的方法吗?

3 个答案:

答案 0 :(得分:4)

这是因为属性仅在编译器知道它必须处理的类时才起作用。 NSObject没有名为field1的属性,因此无效。

但是,您可以使用隐式创建的field1 方法属性:

NSString* str = [aClass field1];

但如果你在NSObject上进行,它会发出警告。

如果您不知道您将拥有哪两个类,并且他们没有任何类关系,我建议您使用id类型而不是NSObject。使用id,编译器不会发出有关可能会失败的方法调用的警告(但仍无法解析您的属性)。

答案 1 :(得分:1)

所有编译器都知道aClass是它的NSObject,所以你只能这样对待它。否则,如果在aClass指向NSString时尝试访问field1会发生什么?使用所需的实例变量创建一个超类,并将aClass声明为该类型。这确保了aClass将包含一个field1变量,这样你就可以继续进行,而不会让糟糕的编译器感到困惑。

您无法从NSObject转换为Class1的原因遵循相同的原则。 aClass可以是任何东西,并且编译器不知道如何对Class1做任何事情。你可以抛出另一种方式,因为所有的aClass都是NSObjects,但并不是所有的NSObject都是aClass。 :d

答案 2 :(得分:0)

为什么不从一个实现您尝试定义的属性的基类继承两个可能的类?

或者,使用两个类实现的属性创建一个类别,而不是定义一个NSObject变量:

id <MyClassCategory> aClass;