在Objective-c中,当我们按惯例将一个类的对象用于另一个类时,我们应该在.h文件中声明该类,即@class classname;
。并且应该在.m文件中导入头文件,即#import "header.h"
。
但是如果我们在.h中导入头文件,那么我们不必再在.m文件中导入它。
那么这个大会背后的原因是什么?哪种方式有效?
答案 0 :(得分:16)
那么这个惯例背后的原因是什么?
你应该在可能的情况下支持前向声明(@class MONClass;
),因为编译器在使用之前需要知道typename是一个objc类,并且因为#import
可以拖入大量其他头文件(例如整个框架/库),严重扩展和复杂化您的依赖项并增加构建时间。
哪种方式有效?
前瞻性声明。如果您正确执行此操作,您的构建,重建和索引将会更快 。
答案 1 :(得分:4)
你是正确的,导入.h中的标题变得更容易(在短期内)。不执行此操作并将其导入实现文件(.m)的原因是为了防止名称污染,其中导入标头中的所有名称在有人导入标头时可用。相反,通过导入标题,只需导入您的函数/类,其余的都在实现
此外,如果您在.h中导入标题,这意味着当第三方标题更改时,即使标题中没有任何更改,也必须重新编译导入标题的每个代码。前向声明避免了这个问题,并强制只重新编译那些实际使用第三方标题的实现(.m)文件
答案 2 :(得分:2)
尽管在.m中导入文件可以更容易地使用几行代码,但一般认为导入可能会影响加载时间和响应时间,是的,它确实会影响和不会。因为根据文档提供的苹果: -
如果您担心包含主头文件可能会导致程序膨胀,请不要担心。因为Mac OS X接口是使用框架实现的,所以这些接口的代码驻留在动态共享库中,而不是在可执行文件中。此外,只有程序使用的代码在运行时才被加载到内存中,因此内存占用空间同样很小。
至于在编译期间包含大量头文件,再一次不用担心。 Xcode提供了预编译的头文件工具,以加快编译时间。通过一次编译所有框架头文件,除非添加新框架,否则无需重新编译头文件。与此同时,您可以使用所包含框架中的任何接口,而几乎没有性能损失。
因此,响应和加载时间仅在第一次受到影响,但无论如何,前向引用应该更有利于维护编码标准并避免开销,但是很小:)。
答案 3 :(得分:0)
#import
是一个预处理器指令,在编译器看到它之前对该文件进行操作。每当您感到困惑时,从概念上将其视为复制粘贴:当您看到#import foo
时,意味着文件foo的内容会在此处插入。 (它比那更聪明,因为它也防止重复包括)。
如果#import Foo.h
中有引用Bar.h
的声明,那么Bar.h
中的Foo.h
就是Bar.h
。如果Bar.m
中没有任何内容使用Foo,但有Bar.m
,则导入进入{{1}}。将声明仅保留在他们需要的地方。
答案 4 :(得分:-1)
这只是说编译器,如果你使用@class xx;
,我们有一个名为xx的类因为您现在不需要其属性/方法。
在下一种情况下,您还需要属性和方法,因为您必须访问它们。如果在.h文件中使用@class xx并且不导入xx.h,则会出现问题。然后声明xx的对象将不会生成和错误但访问它的方法将生成警告并且访问属性会生成错误