提问人:Nuzhdin Vladimir 提问时间:11/24/2016 最后编辑:Nuzhdin Vladimir 更新时间:11/24/2016 访问量:34
如果使用了类别但未添加到目标中,则没有警告(任何方法都会自动检查它?
No warnings if category is used but isn't added into target(Any way check it automatically?)
问:
我有一个类别“NSObject+completeOnce”。我用它来做主应用程序、手表、小部件。但我还没有将其添加到监视和小部件目标中。我当然必须这样做。
我的问题是:“为什么在这种情况下我看不到任何警告或链接错误?我能强迫他们吗?我的项目中有 100 多节课,有时会做这样的 mitakes :(最好在跑步前找到一些方法来检查它。
类别声明:
//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% 唯一方法名称的自定义类的类别。
答:
2赞
Itai Ferber
11/24/2016
#1
你所看到的是一个复合问题。你查找两种类型的错误是正确的 - 编译器警告/错误和链接器错误。你也得不到,原因有二:
- 实际上,编译器没有理由给你一个警告。为了进行方法调用,编译器只需要声明方法(以便正确排列参数、防止常见的用户错误等)。它实际上不需要知道该方法将以某种方式链接;这是链接者的工作。在这种情况下,由于您确实在标头中声明了方法并包含标头,因此编译器是满意的,并且您不会收到警告,因为就编译器而言,该方法稍后将存在。
- 链接器不会为缺少的方法提供错误,因为 Objective-C 不会为方法生成链接器符号(请参阅该页上的 Objective-C 标头)。Objective-C 本质上是一种非常动态的语言,因此在运行时之前不可能知道特定方法调用将做什么;事实上,可以在运行时定义静态不存在的方法。链接器只需要它所具有的类信息;方法的评估由运行时决定。
这两件事结合在一起,导致了你所看到的行为。确保这些方法不存在的唯一方法是简单地尝试在运行时调用它们 - 现在,你会得到一个异常(如果未捕获,会导致崩溃),因为它们实际上并没有包含在应用程序二进制文件中。
评论
0赞
Nuzhdin Vladimir
11/24/2016
我认为你是对的。但我正在寻找一些方法来避免将来发生此类崩溃。可能是没有解决方案。但我认为我至少必须尝试一下。因为我使用“小部件”和“Apple Watch”。项目中有 1000+ 个文件。而且我无法自己检查它=(。这样的错误在一个月内一次又一次地出现,就像那个拿着勺子的人=(youtube.com/watch?v=9VDvgL58h_Y
0赞
Nuzhdin Vladimir
11/24/2016
可能我的问题标题与我的需求不符=(我会尽量在这方面更准确。
1赞
Itai Ferber
11/26/2016
@ZevsVU 没有编译器支持的解决方案,因为不可能有编译器支持的解决方案,由于上述原因——根本没有办法静态地知道这些方法是否存在。但是,您可以使用工具来解决这个问题:您可以编写一个脚本,该脚本会自动遍历项目中的所有文件,并确保将它们添加到所有目标中。或者,如果您有一个文件列表,这些文件应该位于某些目标上而不是其他目标上,请将它们添加到相应的目标中。
评论
.m