如果使用类别但未添加到目标中,则不会发出警告(以任何方式自动检查?)

时间:2016-11-24 06:31:45

标签: objective-c xcode compilation warnings objective-c-category

我有一个类别" NSObject + completeOnce"。我将它用于主应用程序,手表,小部件。但我还没有把它添加到手表和小工具目​​标中。当然,我必须这样做。

我的问题是:"为什么在这种情况下我没有看到任何警告或链接错误?我可以强迫他们吗?"我的项目中有100多个课程,有时会做这样的尝试:(在runnig之前找一些方法来检查它会很好。

类别声明:

//Category is added only into main target.
@interface NSObject (completeOnce)
+ (void)completeBlockOnce:(void(^)(void))block forKey:(NSString*)key
@end

用法:

@implementation SomeOtherClass
+ (void)method
{
    //It crashes for for widgets.
    //And Here is no any warnings. Also no linking errors at all
    [NSObject completeBlockOnce:^{
       //Some Code
    } forKey:@"FixMigrationBug_1_0_to_1_6"];
}
@end

我确信我只有一个这种方法的声明。我必须强调,所有类别都是同样的问题。即使是我的自定义类的类别,也有99%的唯一方法名称。

enter image description here

1 个答案:

答案 0 :(得分:2)

您所看到的是一个复合问题。您正在寻找两种类型的错误 - 编译器警告/错误和链接器错误。你也没有,原因有两个:

  1. 实际上没有理由让编译器给你一个警告。为了让你进行方法调用,所有编译器需要的是方法的声明(因为它可以正确排列参数,防止常见的用户错误等)。它实际上并不需要知道该方法将以某种方式链接;这是链接器的工作。在这种情况下,由于您确实在头中声明了方法并包含头,因此编译器会满意并且您不会收到警告,因为就编译器而言,该方法将在以后存在。
  2. 链接器不会为缺少的方法提供错误,因为Objective-C does not produce linker symbols for methods(请参阅该页面上的Objective-C标头)。 Objective-C本质上是一种非常动态的语言,因此在运行时之前不可能知道特定方法调用会做什么。实际上,可以在运行时定义静态不存在的方法。链接器只需要它拥有的类信息;方法的评估留给运行时。
  3. 这两件事合起来导致你所看到的行为。确保这些方法不存在的唯一方法是简单地尝试在运行时调用它们 - 现在,你得到一个异常(如果未被捕获,导致崩溃),因为它们实际上并没有包括在内在应用程序二进制文件中。