我从这段代码中得不到任何错误:
NSArray* animals = [NSArray arrayWithObjects:
[[Dog alloc] init],
[[Cat alloc] init],
nil];
for (Dog* dog in animals) {
if ([dog respondsToSelector:@selector(bark)]) {
[dog bark];
}
}
以下是狗和猫类:
//
// Dog.h
// Test1
#import <Foundation/Foundation.h>
@interface Dog : NSObject
- (void) bark;
@end
...
//
// Cat.h
// Test1
//
#import <Foundation/Foundation.h>
@interface Cat : NSObject
@end
...
//
// Cat.m
// Test1
//
#import "Cat.h"
@implementation Cat
@end
而且,如果我这样做,我只会收到警告:
Dog* myDog = [[Cat alloc] init];
答案 0 :(得分:2)
看来你在评论中回答了大部分问题,但我想我会写一个答案来填补任何遗漏的空白。
NSArray接受一个id,你可以传入你想要的任何NSObject子类,编译器将允许它。这不是推荐的,但可以完成。
for column in range(self.width):
dummy_temp_line = [self.grid[x][column] for x in range(self.height)]
更酷的是,当你从阵列中拉出物品时,它们就会成为一个id。这会被转换为您正在使用的任何变量。
NSArray* animals = [NSArray arrayWithObjects:
[[Dog alloc] init],
[[Cat alloc] init],
@"This is a string",
@(42),
nil];
如果你这样做,编译器不会吓坏你。
Dog *dog = animals[0];
Cat *cat = animals[1];
这是你在日志中得到的......
NSString *aString = animals[0];
NSLog(@"%@", aString);
NSLog(@"%@", [aString lowercaseString]);
您正在将NS转换为允许的NSString,但是,您尝试调用Dog上不存在的方法,并且会在第二个NSLog上崩溃。请注意,第一个日志表明它仍然是一个Dog,即使它是一个NSString。
现在,如果我们向Dog.h添加一个属性,我们可以在for循环中看到一些简洁的东西。
Dog.h
2015-06-07 08:55:53.715 DogsAndCats2[5717:4029814] <Dog: 0x7fe790c71b80>
2015-06-07 08:55:53.715 DogsAndCats2[5717:4029814] -[Dog lowercaseString]: unrecognized selector sent to instance 0x7fe790c71b80
现在我们循环时考虑以下内容。
#import <UIKit/UIKit.h>
@interface Dog : NSObject
@property (nonatomic, strong)NSString *dogName;
-(void)bark;
@end
希望能回答你的更多问题并且不会太混乱。