为什么可以在for-in循环中将一种类型的指针分配给另一种类型的指针?

时间:2015-06-07 01:43:55

标签: objective-c pointers types for-in-loop

我从这段代码中得不到任何错误:

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

1 个答案:

答案 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

希望能回答你的更多问题并且不会太混乱。