什么是 @class 和 #import 的区别

10 浏览
0 Comments

什么是 @class 和 #import 的区别

当我使用以下代码进行编译时,没有错误:

@class RootViewController;
//#import "RootViewController.h"

当我使用以下代码进行编译时,出现错误:

//@class RootViewController;
#import "RootViewController.h"

"错误:在'RootViewController'之前缺少指定符合条件的列表"

我不明白这两者之间的区别是什么,因为我在一个类似的类中使用了#import,并且编译时没有错误!

0
0 Comments

@class和#import之间的区别是什么?出现这个问题的原因是什么?有什么解决方法?

在Objective-C中,使用`@class`和`#import`来引入类或协议的声明。它们在使用的场景和功能上有所不同。

`@class`用于在头文件中声明一个类,而不需要引入整个类的实现。使用`@class`可以避免循环依赖,提高编译速度。它只是告诉编译器,在某个地方会有一个名为`MYControl`的类被定义。

`#import`则用于在实现文件中引入其他类或协议的头文件。使用`#import`会将整个头文件内容导入到当前文件中,可以使用类的方法和属性。使用`#import`可以避免重复导入同一个文件,提高编译效率。

出现这个问题的原因是为了解决循环依赖和提高编译速度。循环依赖指的是两个或多个类互相引用对方的头文件,导致编译错误。使用`@class`可以在头文件中先声明一个类,然后在实现文件中引入该类的头文件,从而解决循环依赖问题。

解决方法是在头文件中使用`@class`来声明一个类,然后在实现文件中使用`#import`来引入该类的头文件。这样可以解决循环依赖问题,并提高编译速度。

以下是一个示例,演示了在某些情况下必须使用`@class`:

//MYControl.h
@class MYControl;  // 必须使用@class
@protocol MYControlDelegate
-(void)control:(MYControl *)control didChangeToState:(UIControlState)state;
@end
@interface MYControl : UIControl
@property (nonatomic, assign) id delegate;
@end
//MYControl.m
@implementation MYControl
@synthesize delegate = delegate_;
. . .
@end

在这个示例中,头文件中的协议声明位于主类之前,所以不需要使用`#import`来引入其他类的头文件。但是仍然需要能够引用尚未声明的主类。所以使用`@class`只是告诉编译器,有一个名为`MYControl`的类将在某个时候被定义(在编译过程中定义)。

总之,使用`@class`和`#import`的主要区别是,`@class`用于在头文件中声明一个类,避免循环依赖和提高编译速度;而`#import`用于在实现文件中引入其他类或协议的头文件,让编译器可以使用类的方法和属性。通过正确使用这两个关键字,可以解决循环依赖和提高编译效率的问题。

0
0 Comments

@class和#import之间的区别是,在需要知道特定文件中的类名,但不需要知道类的任何细节(例如其方法)时,使用@class;而在实际需要使用类(即发送消息)时,使用#import。

例如,在头文件中声明实例变量时,可以使用@class来声明特定类型的实例变量。因为还没有使用myIvar,所以除了知道类型MyOtherClass存在之外,不需要知道任何关于它的信息。

然而,在发送doSomethingElse消息给myIvar时,编译器需要知道MyOtherClass的实例是否定义了这个方法,因此必须导入头文件,否则编译器会报错。

为什么要关注这个区别呢?这主要与依赖性有关。当你将文件A导入文件B时,文件B就会依赖于文件A,也就是说,如果文件A发生了变化,你就需要重新编译文件B。如果在文件B中使用@class,那么文件B就不依赖于文件A,因此当文件A发生变化时不需要重新编译文件B。所以,如果只是声明一个类型而不依赖于文件A的实现,可以通过不导入文件A来节省编译时间。

@class和#import的区别在于是否需要知道类的具体实现细节以及是否需要依赖于被导入的文件。

0
0 Comments

在Objective-C编程中,我们经常会使用@class和#import来引入其他类的接口文件。虽然它们的作用有些相似,但它们之间有一些重要的区别。

首先,我们来看一下@class。它是一个关键字,用于向编译器声明一个类的存在。当我们在一个类的头文件中使用@class声明另一个类时,我们只是告诉编译器这个类的名称,而不需要包含它的接口文件。这在解决循环引用的问题时非常有用,因为两个相互引用的类可以使用@class来引用对方,而不需要在头文件中相互包含。这样,我们只需要在实现文件中使用#import来引入对方的接口文件即可。

接下来,我们来看一下#import。它是一个预处理指令,用于在编译时将指定的文件内容包含到当前文件中。与#include不同的是,#import会确保同一个文件不会被多次引入,避免重复定义的问题。因此,在Objective-C中,#import更常用,并且在官方文档和示例代码中经常使用。

@class和#import的区别在于,使用@class只是告诉编译器一个类的存在,而使用#import会将整个类的接口文件包含到当前文件中。这意味着,当我们使用@class时,我们只能使用该类的名称作为类型,而不能访问它的方法和实例变量。只有当我们需要使用该类的方法和实例变量时,才需要使用#import来引入它的接口文件。

总结一下,@class和#import都是用于引入其他类的接口文件,但它们之间有一些重要的区别。@class只是告诉编译器一个类的存在,而#import会将整个类的接口文件包含到当前文件中。因此,当我们只需要使用一个类的名称时,可以使用@class来提高编译速度和解决循环引用的问题。而当我们需要使用一个类的方法和实例变量时,必须使用#import来引入它的接口文件。

参考链接:[http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html#//apple_ref/doc/uid/TP30001163-CH12-TPXREF123](http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html#//apple_ref/doc/uid/TP30001163-CH12-TPXREF123)

0