我们可能都不太分的清.h文件和.m文件里各种结构的用途和区别,那我们来仔细的区分一下。
首先写一个class类:
.h文件:
@interface ClassName{ NSString* _value; } @property(nonatomic,assign)NSString* value; -(void)func;
.m文件:
@interface ClassName(){ } @end @synthesize value; @implementation ClassName -(void)func{ } @end
大体上就是这个格式。很多人,包括我,在创建和使用Class时,直接就使用这样的模板。这个模板里有一些有意思的小东西,值得探讨,比如:
1. 为什么.h文件和.m文件里各有1个@interface
?它们分别有什么用?
2. .h中,value为什么要定义2遍?
3. @synthesize
有什么用?
还有一些其它的问题,今天先解决上面提到的这几个。
为什么.h文件和.m文件里各有1个@interface?它们分别有什么用?
.h里面的@interface
,不消说,是典型的头文件,它是供其它Class调用的。它的@property
和functions,都能够被其它Class“看到”。
而.m里面的@interface
,在OC里叫作Class Extension,是.h文件中@interface
的补充。但是.m文件里的@interface
,对外是不开放的,只在.m文件里可见。
因此,我们将对外开放的方法、变量放到.h文件中,而将不想要对外开放的变量放到.m文件中(.m文件的方法可以不声明,直接用)。
有的同学看到Class Extension,可能会想到OC里的@protocol
。是的,它们都是对一个Class的扩展。不过它们的区别也很明显:
Class Extension只能用在能得到源代码的情况下,而@protocol
在得不到源码的时候也可以使用。
因此@protocol
一般用作对一些系统Class的扩展,常见的比如对NSString、UIView等。
.h中,value1为什么要定义2遍?
当然,现在@interface{}
里的定义也可以省略掉了,不过原理还是要搞清楚。
严格来说@interface{}
里定义的变量,叫作instance variable,它是这个Class内部真正的全局变量。然而这个instance variable是不对外公开的,因此我们还需要一个对外公开的东西来调用,就是@property
@property是对外的,它其实是告诉大家,我这个Class里,有一个变量的set/get方法。比如,@property NSString* string;
就是说,本Class里有一个getString/setString供你们调用。
因此需要2次声明。当然现在lldb也升级了,只要你声明了@property
,它就可以自动创建对应的全局变量。
@synthesize有什么用?
@property
一个变量后,在@implementation
里再@synthesize
一下,相信是很多人的习惯。但是为什么要有这个@synthesize方法呢?
@property
是对外声明了Class的get/set方法,然后我们就需要在.m文件里手写get/set方法。这可就麻烦了,1个变量对应2个方法,假如一个Class里有10个变量,那岂不是要写20个方法?烦也烦死唠。
@synthesize帮我们解决了这个问题。@synthesize
在.m文件里自动生成了get/set方法。因此,我们只要在@implementation
后面加上一行:@synthesize
就可以自动生成get/set方法了,省掉了很多麻烦。比如@synthesize value = _value;
的意思就是,将instance variable _value用作getValue和setValue方法里。