剛開始學(xué)習(xí)分類和類擴(kuò)展的時(shí)候很茫然,什么是分類,什么是類擴(kuò)展,他們分別用在什么場(chǎng)合,各有哪些不能被替代的特點(diǎn)?后來(lái)自己寫的多了一些,發(fā)現(xiàn)這真的是很出色的兩種擴(kuò)展類。希望能寫的淺顯易懂,讓更多人能夠理解分類和類擴(kuò)展,并實(shí)際運(yùn)用他們。
分類運(yùn)用場(chǎng)景舉例:想要收集每個(gè)頁(yè)面的啟動(dòng)時(shí)間。
問(wèn)題1:
項(xiàng)目中已經(jīng)有上百個(gè)頁(yè)面了,如果一個(gè)一個(gè)的加,浪費(fèi)時(shí)間不說(shuō),以后增加了新頁(yè)面,還需要添加方法。
解決方法:
我們可以發(fā)現(xiàn)頁(yè)面都繼承了UIViewController,想要在每個(gè)頁(yè)面都執(zhí)行的代碼,可以寫在這些頁(yè)面的父類中。我們可以把代碼寫在UIViewController中。
問(wèn)題2:
UIViewController是官方類,我們只能調(diào)用期接口,并不能修改他的實(shí)現(xiàn)。
解決方法:
使用分類(category)。
1.分類(category)的作用
1.1作用:可以在不修改原來(lái)類的基礎(chǔ)上,為一個(gè)類擴(kuò)展方法。
1.2最主要的用法:給系統(tǒng)自帶的類擴(kuò)展方法。
2.分類中能寫點(diǎn)啥?
2.1分類中只能添加“方法”,不能增加成員變量。
2.2分類中可以訪問(wèn)原來(lái)類中的成員變量,但是只能訪問(wèn)@protect和@public形式的變量。如果想要訪問(wèn)本類中的私有變量,分類和子類一樣,只能通過(guò)方法來(lái)訪問(wèn)。
2.3如果一定要在分類中添加成員變量,可以通過(guò)getter,setter手段進(jìn)行添加,詳細(xì)在分類中動(dòng)態(tài)聲明成員變量的方法(runtime)
3.分類的書寫方法
假設(shè)我們有一個(gè)類,名叫Person,意義是人類。在person類中我們有一個(gè)方法,-(void)eat;意義是吃,因?yàn)槊總€(gè)人類都會(huì)吃。
人類有很多共同特點(diǎn),也有很多不同點(diǎn),比如,并不是每個(gè)人都會(huì)踢足球。這時(shí)候我寫一個(gè)分類,給喜歡運(yùn)動(dòng)的人,這個(gè)分類的名字叫做sport。因?yàn)槭莗erson類的分類,你會(huì)看到生成的名字叫做Person+sport。下面讓我們來(lái)試著添加一下。
0.分類的使用過(guò)程:聲明分類->實(shí)現(xiàn)分類->使用分類
1.在項(xiàng)目中添加類,選擇Objective-C File,在彈出的頁(yè)面中這樣配置。
2.Person+sport.h頭文件
3.Person+sport.m文件
4.回到最開始收集頁(yè)面啟動(dòng)時(shí)間的問(wèn)題,本類是系統(tǒng)的類,這里是UIViewController,我們可以使用分類擴(kuò)展他的方法,也可以重寫他的方法,可以我需要在調(diào)用的地方加頭文件,所有子類都寫頭文件和直接在子類寫方法沒有什么區(qū)別,怎么樣可以使得不寫頭文件,子類就能調(diào)用我們寫的代碼呢?
回答:
我們可以進(jìn)行方法交換(這樣可以不必在調(diào)用的地方增加頭文件),從而使得在實(shí)現(xiàn)的時(shí)候調(diào)用重寫的方法。具體實(shí)現(xiàn)使用runtime交換系統(tǒng)類的方法
4.分類的執(zhí)行優(yōu)先級(jí)
4.1在本類和分類有相同的方法時(shí),優(yōu)先調(diào)用分類的方法再調(diào)用本類的方法。
4.2如果有兩個(gè)分類,他們都實(shí)現(xiàn)了相同的方法,如何判斷誰(shuí)先執(zhí)行?分類執(zhí)行順序可以通過(guò)targets,Build Phases,Complie Source進(jìn)行調(diào)節(jié),注意執(zhí)行順序是從上到下的。(只有兩個(gè)相同方法名的分類)
5.分類(category)和類擴(kuò)展(extension)的關(guān)系
1.類擴(kuò)展(extension)是category的一個(gè)特例,有時(shí)候也被稱為匿名分類。他的作用是為一個(gè)類添加一些私有的成員變量和方法。
2.類擴(kuò)展能寫點(diǎn)啥?和分類不同,類擴(kuò)展即可以聲明成員變量又可以聲明方法。
3.類擴(kuò)展聽上去很復(fù)雜,但其實(shí)我們很早就認(rèn)識(shí)他了。你記得繼承自UIViewController的ViewController和繼承自NSObject的類有什么不同么?
4.繼承自UIViewController的ViewController類
5.對(duì)比看一下繼承自NSObject的類我們會(huì)發(fā)現(xiàn)沒有上面的代碼塊
@interface ViewController()//這就是類擴(kuò)展的寫法
@end