Objective-C 编译器不允许我调用公共(public) API 中不存在的方法

标签 objective-c

我开始通过观看 YouTube 讲座来学习 Objective-C。在一次讲座中,老师说,每当你尝试调用一个对象的公共(public) API 中不存在的方法时,编译器都会警告你,但会让你这样做。另外,如果该方法确实存在,它将在运行时起作用。

举例说明:

我有两个类(class):车辆和船舶。 Vehicle 实现了移动方法,而 Ship 是 Vehicle 的方法并实现了射击

在讲座中,据说这段代码可以编译(带有警告):

Ship *s = [[Ship alloc] init];
Vehicle *v = s;
[v shoot];

事实上,这段代码是可以工作的。因为v实际上是一艘船。

但实际情况是编译器不允许我编译这段代码,因为在 Vehicle 公共(public) API 中不存在 shot。

编译器错误:“Vehicle”没有可见的@interface声明选择器射击

我真的很想知道老师是否错了或者我是否可以改变编译器的行为。有人可以帮助我吗?谢谢!

观察:我知道我可以使用 (id) 来做到这一点,我真的很想在这里了解有关 Objective-C 行为和语法的更多信息

类(class):

车辆.h:

@import Foundation;

@interface Vehicle : NSObject

- (void) move;

@end

车辆.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

最佳答案

你的老师是对的,但他忘了提到一些重要的事情:他描述的语义是 pre-ARC 的。

几年前引入 ARC 后,编译器的类型检查变得更加重要,因为它需要知道确切的签名才能知道如何管理进出调用的数据。请参阅this question更详细地解释为什么会发生这种情况。

如果关闭 ARC,您会看到警告,但代码会编译。

关于Objective-C 编译器不允许我调用公共(public) API 中不存在的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28522251/

相关文章:

objective-c - Objective C 比较 NSDate 中的两个日期字符串

iphone - 如何获得 objective-c 中一周中的特定一天?

ios - 在 objective-c 中访问类方法。使用 self 或类名?

objective-c - AppDelegate 未找到 ViewController 的声明和合成属性

ios - 在 Core Data 中存储关系中尚不存在的对象数

objective-c - iOS - 如何使用无序的 CGPoints 绘制特定的 CGPath

ios - 无法根据 objective-c 中标签的文本大小设置单元格大小

iOS CLLocationManager : Removing spikes

ios - 显示 UILabels 和 UIButtons Inline 彼此的方法

iphone - UITableView 帧变化动画问题