2015-12-21 29 views
1

快速的问题。我有一个没有实现文件的类的项目。是否有编译器标志,以便链接器警告我这个? .h文件不带.m文件

然后在AppDelegate中我有:

#import "AppDelegate.h" 
#import "SomeClass.h" 
@interface AppDelegate() 

@property (nonatomic, strong) SomeClass *myProperty; 

@end 

@implementation AppDelegate 


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

    [self.myProperty hello]; 

// self.myProperty = [[SomeClass alloc] init]; // uncomment and fails as expected. 

    return YES; 
} 

不应该有人告诉我,有没有实现文件?某种警告或任何事情?

如果我做了一个alloc] init],它不会按预期编译。

该代码实际编译。

这是github中的项目。

https://github.com/nmiyasato/noImplementation

由于

+0

如果某个类没有实现,它将无法链接。警告通常是用于编译和链接的东西,但可能是错误的。 – dan

+0

应该有一个扩展名为.a的库文件,或者应该有一些与之相关的SDK(框架)。 – Smile

+0

该代码实际编译...我已经添加了一个示例项目。 – miya

回答

3

号这不是在编译时或在目标C的链接时间检测的。

首先,编译器确切地知道没有关于“头文件”或“实现文件”的。 (这与新的模块系统稍有不同,但这不是我们在这里讨论的。)

#import不由编译器处理。它由预处理器处理。它需要文件SomeClass.h并在编译器甚至看到第一行之前以文本的形式将其写入AppDelegate.m。因此,所有编译器必须使用的是这个巨大的文件,其中包含所有头文件的所有文本以及此实现(尽管现在有“整个模块优化”,这是一个链接步骤,而不是编译步骤)。它无法访问项目的其余部分。

所以编译器无法知道你没有提供实现。而在ObjC中,即使编译器查看了所有的代码,也无法真正知道在任何地方都没有实现,因为您可以在运行时添加实现。其实,这很漂亮这样做通常。这就是所有核心数据的工作原理。这些实现也可以通过共享框架(这是很常见的)连接起来,并且甚至可以在OS X上的运行时链接到该实现。或者实现可能位于静态库中,因此缺少.m仍然没有帮助。

它甚至有可能的self.myProperty结果是随机的“其他东西”,也就是只假装SomeClass。是的,我知道这听起来很疯狂。欢迎使用Core Foundation桥接的类集群。这是一件事。所以甚至可能没有以你想的方式实施。 Objective-C是一个非常疯狂的动态语言。

作为一个例子,下面是合法的ObjC(它甚至工作):

@interface NSString (Hello) 
- (void)hello; 
@end 

@implementation NSString (Hello)  
- (void)hello { 
    NSLog(@"I'm string's Hello!"); 
} 
@end 

... 
self.myProperty = (SomeClass *)@""; 
[self.myProperty hello]; 

你会认为也许可以连接数字出来,但当时我们得到的链接,所有的对象类型为id,所有方法都只是选择器和方法签名。大部分类型信息都没有了。

那么,如果你打电话给[[SomeClass alloc] init],为什么不能链接?首先注意到它编译,它只是不链接。原因是[self.myProperty hello]是一个对象的消息。链接器不知道或关心对象的类型。它只需要一个指向实例的指针。但[SomeClass alloc]是一个类的消息。为了链接它,链接器必须有一个指向类的指针。你会发现任何没有实现的类的消息都会导致链接器错误(尝试[SomeClass initialize])。

在你的代码中没有任何反应,因为self.myProperty是零,所以没有错误。即使你有一个实现,这也是一样的。在绝大多数情况下,缺少实现文件将在链接期间被捕获,因为某处在您的系统中,您可能会拨打+alloc。所以在实践中,这不应该经常出现,而且这种罕见的情况在不破坏大量合法的ObjC的情况下极难检测到。

相关问题