打個(gè)比方:
一個(gè)person類中有一個(gè)屬性age,那么如果用property聲明后,set跟get方法僅僅只是做一個(gè)_age = age.但是你想想如果你在person類中new一個(gè)對(duì)象p,那么我可不可以寫(xiě)成 p setAge = -10 ?
一個(gè)人的年齡肯定不會(huì)有-10歲,如果重寫(xiě)set方法你就可以在set方法中寫(xiě)成
if(age <= 0){
age = 1;
}
也就是說(shuō)當(dāng)你給age賦值小于或等于0的時(shí)候,age會(huì)自動(dòng)變成1,一個(gè)人的年齡是1歲,也比-10歲來(lái)的合理.
另一種場(chǎng)合:
子類重寫(xiě)父類中的方法:
在子類中實(shí)現(xiàn)與父類中同名的方法,稱之為方法重寫(xiě);
重寫(xiě)以后當(dāng)給子類發(fā)送這個(gè)消息的時(shí)候,執(zhí)行的是在子類中重寫(xiě)的那個(gè)方法,而不是父類中的方法。
如果想在子類中調(diào)用被子類重寫(xiě)的父類的方法,可以通過(guò)super關(guān)鍵字
使用場(chǎng)景:當(dāng)從父類繼承的某個(gè)方法不適合子類,可以在子類中重寫(xiě)父類的這個(gè)方法。
關(guān)于重寫(xiě)init方法:
重寫(xiě)init方法時(shí),必須要在init方法中調(diào)用父類的init方法即:[super init],且[super init]必須要用self來(lái)接收它的返回值,否則報(bào)錯(cuò)。
super調(diào)用的init方法必須要接收,用self接收。
可以這么理解:我們使用到的Person對(duì)象需要通過(guò)init返回,而Person中的self指針沒(méi)有被初始化,所以不知道self指向的是誰(shuí),所以需要將[super init]返回的對(duì)象內(nèi)存空間賦給self指針,這樣self指針就明確指向了當(dāng)前的內(nèi)存空間,所以Person的init方法返回了Person的對(duì)象,同時(shí)初始化了self指針,當(dāng)我們使用self指針時(shí),就知道self指向的是哪塊內(nèi)存空間了。
懶加載:
理念:變量不到需要使用的最后一刻,就不要分配空間。什么時(shí)候用到變量了,什么再分配
實(shí)現(xiàn)措施:重寫(xiě)該屬性的getter方法,在getter方法中做判斷,當(dāng)沒(méi)有分配空間時(shí),先分配再返回,如果已經(jīng)有空間了,那么就直接返回
懶加載的優(yōu)點(diǎn):
1.不需將對(duì)象的實(shí)例化寫(xiě)到viewDidLoad,可以簡(jiǎn)化代碼,增強(qiáng)代碼的可讀性
2.對(duì)象的實(shí)例化在getter方法中,各司其職,降低耦合性
3.對(duì)系統(tǒng)的內(nèi)存占用率會(huì)減小
沒(méi)用懶加載的時(shí)候,從plist獲取數(shù)據(jù),返回一個(gè)數(shù)組,需要寫(xiě)在viewDidLoad方法中獲取
@interface ViewController ()
@property (nonatomic, strong) NSArray *students;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_students = [NSArray arrayWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"students" ofType:@"plist"]];
}
@end
顯而易見(jiàn),當(dāng)控制器被加載完成后就會(huì)加載當(dāng)前的students,假如students是在某些事件被觸發(fā)的時(shí)候才會(huì)被調(diào)用,沒(méi)必要在控制器加載完就去獲取plist文件,如果事件不被觸發(fā),代表著students永遠(yuǎn)不會(huì)被用到,這樣在viewDidLoad中加載students就會(huì)十分多余,并且耗用內(nèi)存.
懶加載代碼示例:
- (void)viewDidLoad {
[super viewDidLoad];
}
- (NSArray *)students
{
if (!_students) {
_students = [NSArray arrayWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"students" ofType:@"plist"]];
}
return _students;
}
@end
當(dāng)需要用到students的時(shí)候,就會(huì)調(diào)用[self students]的方法(即getter方法),此時(shí)系統(tǒng)會(huì)去調(diào)用getter方法,然后再getter方法中獲取plist文件內(nèi)容,然后返回使用
需要注意在getter方法里切勿使用self.students,因?yàn)閟elf.students會(huì)調(diào)用getter方法,造成死循環(huán)
_students是直接值訪問(wèn),而self.students是屬性訪問(wèn),就是通過(guò)get/set方法來(lái)讀取這個(gè)值,xcode會(huì)默認(rèn)將兩個(gè)值通過(guò)syncthesize關(guān)鍵字進(jìn)行同步
舉個(gè)例子:
- (UIButton *)cover這個(gè)方法就是self.cover的get方法,也就是說(shuō)每次你調(diào)用self.cover的時(shí)候都會(huì)進(jìn)入這個(gè)方法,那么問(wèn)題來(lái)了
如果你在這個(gè)方法里用了下面這個(gè)語(yǔ)句
if (self.cover == nil );邏輯上就行不通,因?yàn)槟阍谶@里調(diào)用self.cover他會(huì)再一次進(jìn)入這個(gè)方法,理論上就會(huì)死循環(huán)
而_cover是直接值訪問(wèn)的,他不會(huì)調(diào)用get/set方法,所以就不會(huì)有這個(gè)問(wèn)題.
至于后面綠色的地方為什么可以就很好理解了,雖然它也會(huì)進(jìn)入get方法,但是他已經(jīng)不等于nil了.會(huì)直接返回他本身,所以沒(méi)有問(wèn)題.