我创建了一个名为Foo
的小组:
@interface Foo:NSObject{
int myInt;
}
@property int myInt;
@end
以及名为Foo
的{{1}}的子类:
Bar
我正在尝试将@interface Bar:Foo{
NSString *myString;
}
@property (copy) NSString *myString;
@end
存储为数组中的Bar
对象,如下所示:
Foo
我这样做是因为我实际上有-(void)createBar{
Foo *object = [[Bar alloc]init];
// myArray is an instance of NSMutableArray
[myArray addObject:object];
}
的多个子类(我不想全部列出)。当我从数组中获取对象并将消息发送到对象以获取Foo
变量时,应用程序不执行任何操作。 示例:
myString
我是否误解了'信息'是如何运作的?我假设我可以向对象发送消息,无论是否存在,它都会调用它。我需要以其他方式做这件事吗?该数组将包含所有不同类型的-(NSString *)getStringFromFooAtIndex(NSUInteger)index{
Foo *object = [myArray objectAtIndex:index];
return [object myString];
}
子类,我需要它来存储它们。
答案 0 :(得分:3)
我假设我可以向对象发送消息,无论是否存在,都会调用它。
您确实可以向任何对象发送任何消息;这是Objective-C乐趣的一部分。 变量的类型(Foo *
,Bar *
,id
或其他任何内容)对邮件发送无效。变量点知道其类的对象。相应方法的查找是在运行时通过该类完成的。编译器将括号中的表达式转换为对函数objc_msgSend
的调用。
你应该在构建时收到关于[object myString]
的警告,说“'Foo'可能不响应'myString'” - 编译器知道至少有一个类的某个地方有一个对应于{的方法{1}},它知道在编译时,myString
似乎不是其中之一,但它不能保证Foo
无法做到在运行时与消息的东西。消息可以解析in custom ways during runtime。请注意,如果将变量的类型更改为Foo
,警告将消失 - 编译器无法再推断可用的方法。
如果事实证明您发送的id
对象没有响应(即,如果对象确实是 a {{1} }而不是myString
或Foo
的一个未实现Bar
的子类,将引发异常。这是默认响应(通过从Foo
继承的任何内容)到无法识别的消息。
如果您有需要发送消息的异构对象集合,则可能需要先测试每个对象。你可以像jstevenco建议的那样做,并测试功能性:
myString
或测试身份:
NSObject
如果对象是if( [object respondsToSelector:@selector(myString)] ){
或任何if( [object isKindOfClass:[Bar class]] ){
的子类,后者将通过。使用Bar
仅测试您指定的类。
答案 1 :(得分:1)
有关如何处理消息传递逻辑的详细摘要,请参阅here。如果您不覆盖-(void)doesNotRecognizeSelector:(SEL)aSelector
,最终会产生错误。
如果您要拥有多态对象集合,则应首先使用respondsToSelector:
测试该对象,然后根据需要直接调用该方法或使用performSelector:
变体之一。另一种可能性是在基类中包含myString
的实现,它不执行任何操作。
答案 2 :(得分:0)
我弄清楚问题是什么。
在我的AppDelegate.m文件中,我有以下方法:
- (void)createFoo{
Foo *foo = [[Bar alloc]init];
[myArrayController add:foo];
}
这是将'foo'对象插入我的数组控制器。我也定义了这个方法:
- (void) insertObject:(Foo *)object intoMyArrayControllerAtIndex:(NSUInteger)index{
// handles the inserting of the object as well as working with the undo manager
}
现在,调用[myArrayController add:foo]
是造成问题的原因。如果我用[self insertObect:foo intoMyArrayControllerAtIndex:0]
替换该行,那么一切都很完美。
非常感谢你,对不起浪费你的时间。