例如,我有以下界面。
#import<UIKit/UIKit.h>
@interface someClass : NSObject
@property (nonatomic, copy) NSString *string;
@property (nonatomic, copy) UIFont *font;
@end
我觉得我们不必要地导入了整个UIKit。我不确定以下是否会比上面好。
#import<Foundation/Foundation.h>
#import<UIKit/UIFont.h>
@interface someClass: NSObject
@property (nonatomic, copy) NSString *string;
@property (nonatomic, copy) UIFont *font;
@end
我认为只导入UIKit我可以解决不需要列出所有其他所需框架的问题。但这样做有什么真正的优势/劣势吗?此外,如果不是使用#import,我使用@import模块将在这个特定的例子中有所作为。
答案 0 :(得分:2)
理论上,是的。这就是C和Objective-C头的设计方式。您应该只导入所需的组件,因为编译器的工作量较少,因此编译时间更短。如果你看看它们通常如何工作的Apple框架(每个标题只导入它使用的组件)。
在实践中,这将是一项大量工作,您需要维护所需标题的列表,并且您几乎不会看到任何性能改进。这是因为UIKit组件非常捆绑在一起,这意味着你的UIFont.h
标题将导入其他UIKit标题,而这些标题又会导入其他标题等等...而且你每次都会导入大部分UIKit
正如您所提到的,真正有所作为的是一个名为Modules的编译器功能,需要启用它(但我相信它默认启用,在Xcode构建设置中检查Enable modules
)。当您使用模块(例如UIKit模块)时,编译器会在第一次导入时编译整个模块,然后对其进行缓存。然后,源文件中相同模块的所有其他导入将使用此缓存版本,这将导致更快的编译时间。
默认情况下,您可以通过执行@import UIKit;
导入UIKit模块,但编译器也会将#import<UIKit/UIKit.h>
理解为UIKit模块的导入(如果模块已启用),因此它的工作方式相同方式。
您也可以使用点表示法导入模块的一部分(例如@import UIKit.UIFont;
),但请记住,这仍然会触发整个模块的编译和缓存,所以不要将其视为性能提升。同样,编译器会将#import<UIKit/UIFont.h>
理解为@import UIKit.UIFont;
。
所有这些都说明了,问题的答案是:#import<UIKit/UIKit.h>
和#import<UIKit/UIFont.h>
会产生完全相同的效果影响。你应该使用第一个,因为它更容易,感谢编译器的作者,并且再也不会考虑它了!