開發(fā)iOS好幾年的老鳥,可能都不太分的清.h文件和.m文件里各種結(jié)構(gòu)的用途和區(qū)別。最近仔細研究了一下刺洒,寫一篇文章記下來。
一般的吼砂,寫一個Class的時候逆航,經(jīng)常是這種格式(以UIViewController為例):
.h文件:
@interface ClassName{
NSString* _value1;
}
@property(nonatomic,assign)NSString* value1;
-(void)func1;
.m文件:
@interface ClassName(){
}
@end
@synthesize value1;
@implementation ClassName
-(void)func1{
}
@end
大體上就是這個格式。很多人渔肩,包括我因俐,在創(chuàng)建和使用Class時,直接就使用這樣的模板赖瞒。這個模板里有一些有意思的小東西女揭,值得探討蚤假,比如:
1. 為什么.h文件和.m文件里各有1個@interface?它們分別有什么用栏饮?
2. .h中,value1為什么要定義2遍磷仰?
3. @synthesize有什么用袍嬉?
還有一些其它的問題,今天先解決上面提到的這幾個。
為什么.h文件和.m文件里各有1個@interface?它們分別有什么用伺通?
.h里面的@interface箍土,不消說,是典型的頭文件罐监,它是供其它Class調(diào)用的吴藻。它的@property和functions,都能夠被其它Class“看到”弓柱。
而.m里面的@interface沟堡,在OC里叫作Class Extension,是.h文件中@interface的補充矢空。但是.m文件里的@interface航罗,對外是不開放的,只在.m文件里可見屁药。
因此粥血,我們將對外開放的方法、變量放到.h文件中酿箭,而將不想要對外開放的變量放到.m文件中(.m文件的方法可以不聲明复亏,直接用)。
有的同學(xué)看到Class Extension七问,可能會想到OC里的@protocol蜓耻。是的,它們都是對一個Class的擴展械巡。不過它們的區(qū)別也很明顯:
Class Extension只能用在能得到源代碼的情況下刹淌,而@protocol在得不到源碼的時候也可以使用。
因此@protocol一般用作對一些系統(tǒng)Class的擴展讥耗,常見的比如對NSString有勾、UIView等。
.h中古程,value1為什么要定義2遍蔼卡?
當然,現(xiàn)在@interface{}里的定義也可以省略掉了挣磨,不過原理還是要搞清楚雇逞。
嚴格來說@interface{}里定義的變量,叫作instance variable茁裙,它是這個Class內(nèi)部真正的全局變量塘砸。然而這個instance variable是不對外公開的,因此我們還需要一個對外公開的東西來調(diào)用晤锥,就是@property
@property是對外的掉蔬,它其實是告訴大家廊宪,我這個Class里,有一個變量的set/get方法女轿。比如箭启,@property NSString* string; 就是說,本Class里有一個getString/setString供你們調(diào)用蛉迹。
因此需要2次聲明傅寡。當然現(xiàn)在lldb也升級了,只要你聲明了@property北救,它就可以自動創(chuàng)建對應(yīng)的全局變量赏僧。
@synthesize有什么用?
@property 一個變量后扭倾,在@implementation里再@synthesize一下淀零,相信是很多人的習(xí)慣。但是為什么要有這個@synthesize方法呢膛壹?
@property是對外聲明了Class的get/set方法驾中,然后我們就需要在.m文件里手寫get/set方法。這可就麻煩了模聋,1個變量對應(yīng)2個方法肩民,假如一個Class里有10個變量,那豈不是要寫20個方法链方?煩也煩死嘮持痰。
@synthesize幫我們解決了這個問題。@synthesize在.m文件里自動生成了get/set方法祟蚀。因此工窍,我們只要在@implementation后面加上一行:@synthesize 就可以自動生成get/set方法了,省掉了很多麻煩前酿。比如@synthesize value1 = _value1;的意思就是患雏,將instance variable _value1用作getValue1和setValue1方法里。
get/set方法有時候是比較復(fù)雜的罢维,因為它和變量的屬性相關(guān)淹仑,就是@property(nonatomic, assign/retain(strong/weak))這就和內(nèi)存有關(guān)了。然而@synthesize為我們做了這些事情肺孵,就不要再為這些事情煩惱了匀借!
更方便的是,從Xcode4.4開始平窘,編譯器會自動為每一條@property都添加一條對應(yīng)的@synthesize吓肋,因此以后我們只要寫一個@property就可以了!
PS:這些在Swift貌似都不是個事兒了初婆。話說到現(xiàn)在都沒怎么接觸過Swift蓬坡,真是罪過罪過。