Categories

Categories框架

catgory 容許你爲一個已經存在的類增長方法----甚至是一個你沒有source的類。對象

Categories是一種強大的特性,它容許你直接擴展類的功能,而不須要使用子類的方法來擴展。繼承

 

須要注意的是category不能夠爲要擴展的類聲明額外的實例變量;它只能包含方法。然而,全部在類的做用域裏的實例變量也在category的做用域裏。前面的實例變量指的是類裏能聲明過的實例變量,@private的也不例外。作用域

使用categories,你能夠把你本身的類的實現方法分佈在幾個不一樣的文件裏。 爲一個類增長categories的數量是沒有限制的,可是每個category 的名字必需要是不相同的,並且應該聲明和定義一個不一樣的方法集。開發

How You Can Use Categories編譯

使用categories的方式有不少:class

  • 擴展一個其它實施者定義的類

     例如,你能夠爲Cocoa frameworks裏的類增長方法。增長的方法會被子類繼承並且在運行時也不會和原始的方法有任何不一樣。變量

  • 做爲子類的一個替代方式

       不須要定義一個子類來擴展已有的類,經過category你能夠直接爲類添加方法。例如,你能夠爲NSArray和其它的Cocoa classes添加categories.與添加子類的方式來比,你不須要你擴展的類的源代碼。擴展

  • 把實現一個新類的方法分佈在多個源文件裏

     例如,你能夠把一個很大的類的方法分組到幾個categories裏,而後把每一個     category放在本身的文件裏。當以這種方式使用時,categories在不少方面對開發過程都是有幫助的:配置

1.提供一個簡單的方式來組合相關的方法。被定義在不一樣的類裏的類似的方法能夠被保存在同一個源文件裏。

2.當一個類是由多個開發者共同定義的時候,能夠簡化大類的管理。

3.爲一個很是大的類的增量編譯提供方便。

4.提升經常使用方法的本地參考。

5.能夠根據不一樣版本的程序配置不一樣的類,而無需爲不一樣版本保持相同的源代碼。

雖然Objective-C語言目前容許使用category來經過重載繼承的類的方法或者甚至是類文件中的方法,可是這種作法是被強烈反對的。category不是子類的替代品。使用category 來重載

方法有不少重大的缺陷:

  • 當category 重載一個從父類繼承過來的方法,一般能夠經過super關鍵字來調用父類的實現方法。然而,若是category重載一個擴展類自己存在的方法,就沒有喚醒原始實現方法的辦法了。
  • 同一個類的category不能聲明重載這個類的另外一個category中聲明的方法。這一點很是的重要,由於不少Cocoa類也是經過使用categories來實現的。一個你試圖重載的框架中定義的方法可能自己就已經在一個category被實現了,若是你這樣作了,極可能使用得前面的category的方法的實現失效。
  • 一些category methods的存在可能會致使整個框架的行爲發生變化。

     例如,若是你在NSObject的一個category中重載windowWillClose:委託方法,在你的程序裏全部窗口的委託將會使用category方法來回應;全部NSWIndow實例的行爲都會改變。你爲一個框架類增長的Categories可能會致使行爲上很神祕的變化和程序的崩潰。

Categories of the Root Class

Category 能夠爲任何的類添加方法,其中也包括root class。添加到NSObject類上的方法對於全部與你的代碼相關聯的類都是可用的。有時候爲root class添加方法是很是有用的,可是它也是很是危險的。雖然從表面上看起來category所作出的修改能夠被很好的理解,並且影響也是有限的,可是繼承的機制使得它有了一個普遍的做用域。你可能會對你程序裏不可見的類作出意想不到的修改;你可能會對你正在作的事會產生的結果一無所知。甚者,當對你修改過什麼一無所知的人在你的程序上工做時,他們對於他們正在作的事也不會有一個充分的瞭解。

另外,當你爲root class實現方法時有兩點須要記住:

  • 發送消息給super是非法的(由於NSObject沒有超類)
  • 類的對象能夠執行root class中定義的實例方法

正常來講,類對象只能執行類方法。可是root class中定義的實例方法是一個特例。它們定義了一個類,在運行時系統中的全部對象都繼承這個類。類對象是徹底成熟的對象,它須要共享同一個類。

 

這個特性意味着你爲NSObject類在category定義的實例方法不只要能被實例對象執行,並且也要能被類對象執行。例如:在方法體中,self可能表明一個類對象,也多是類的一個實例。

相關文章
相關標籤/搜索