我开始学习Objective-C观看YouTube讲座。在其中一个讲座中,老师说每当你尝试调用公共API中不存在的对象的方法时,编译器将警告你,但是会让你这样做。此外,如果该方法确实存在,它将在运行时工作。
举例说明:
我有两个班:车辆和船。车辆实施方法移动并且发货是车辆的孩子并实施拍摄。
在讲座中,有人说这段代码会编译(带警告):
Ship *s = [[Ship alloc] init];
Vehicle *v = s;
[v shoot];
事实上,这段代码可行。由于 v 实际上是一艘船。
但是在实践中讨厌的是编译器不允许我编译这段代码,因为在Vehicle公共API中不存在shoot。
编译错误:“车辆”没有可见的@interface声明选择器拍摄
我真的想知道老师是错还是我可以改变编译器的行为。有人可以帮帮我吗?谢谢!
Obs。:我知道我可以使用(id)来做,我真的想在这里学习更多有关Objective-C行为和语法的知识
类:
vehicle.h:
@import Foundation;
@interface Vehicle : NSObject
- (void) move;
@end
vehicle.m:
#import "Vehicle.h"
@implementation Vehicle
- (void) move {
NSLog(@"moving");
}
@end
ship.h:
#import "Vehicle.h"
@interface Ship : Vehicle
- (void) shoot;
@end
ship.m:
#import "Ship.h"
@implementation Ship
- (void) shoot {
NSLog(@"shooting");
}
@end
答案 0 :(得分:3)
你的导师是对的,但是他忘记提到一些重要的东西:他所描述的语义是前ARC。
几年前推出ARC时,编译器的类型检查变得更加重要,因为它需要知道确切的签名才能知道如何管理进出呼叫的数据。有关发生这种情况的更详细说明,请参见this question。
如果关闭ARC,您会看到警告,但代码会编译。