1.類(lèi)別(category)
(1)類(lèi)別的出現(xiàn)
編寫(xiě)面向?qū)ο蟮某绦驎r(shí),我們常常要為我們現(xiàn)有的類(lèi)添加新的功能,我們通常會(huì)選擇創(chuàng)建子類(lèi)的方法來(lái)拓展我們的功能需求。但是對(duì)于有些時(shí)候,子類(lèi)并不方便,比如NSString和NSArry這種采用了了類(lèi)簇的類(lèi),創(chuàng)建子類(lèi)時(shí)非常困難,當(dāng)用到一些工具集時(shí),用這些類(lèi)創(chuàng)建的子類(lèi)可能無(wú)法處理,如NSString的stringWithFormat:類(lèi)方法產(chǎn)生的字符串,你的NSString新子可能無(wú)法返回。我們利用OC的動(dòng)態(tài)運(yùn)行分配機(jī)制,可以為現(xiàn)有的類(lèi)添加新方法,這種方法稱(chēng)之為類(lèi)別(category)
(2)類(lèi)別的使用
類(lèi)別是為已經(jīng)存在的類(lèi)添加新方法的Objective-C 2.0語(yǔ)言特性,它的使用場(chǎng)景如下
- 為已經(jīng)存在的類(lèi)添加新方法
- 將自己的類(lèi)方法實(shí)現(xiàn)分散到多個(gè)源文件中
- 聲明私有方法
- 模擬多繼承
- 把框架的私有方法公開(kāi)
其中1為其主要用法;2,3為蘋(píng)果官方推薦的其他用法[Category];4,5說(shuō)法源自美團(tuán)[深入理解的Objective-C:類(lèi)別]
《Objective-C基礎(chǔ)教程》中推薦類(lèi)別代碼置于新文件中,一般以“類(lèi)名稱(chēng)+類(lèi)別名稱(chēng)”的方式命名。如我們?yōu)镹SString添加一個(gè)NumberConvenience的類(lèi)別,命名為NSString+NumberConvenience。類(lèi)別聲明與實(shí)現(xiàn)如下
@interface NSString (NumberConvenience)
- (NSNumber *) lengthAsNumber;
- (NSNumber *) valueAsNumber;
@end //NumberConvenience
@implementation NSString (NumberConvenience)
- (NSNumber *) lengthAsNumber
{
NSUInteger len = [self length];
return ([NSNumber numberWithUnsignedInt:len]);
}//lengthAsNumber
- (NSNumber *) valueAsNumber
{
//code here
}
@end //NumberConvenience
我們可以發(fā)現(xiàn)類(lèi)別來(lái)添加新方法與自定義類(lèi)的形式非常相似,不過(guò)是括號(hào)中指明為類(lèi)創(chuàng)建的新類(lèi)別的名字。
在文件中包含我們的頭文件就可以使用這些新方法了
#import <Foundation/Foundation.h>
#import "NSString+NumberConvenience"
int main(int argc, const char * argv[])
{
NSString * ast = [NSString stringWithFormat:@"123"];
NSNumber * test = [ast lengthAsNumber];
//some code
return 0;
}
注意:
- 使用類(lèi)別無(wú)法向類(lèi)中添加新的實(shí)例變量,類(lèi)別沒(méi)有空間容納實(shí)例變量
- 名稱(chēng)沖突時(shí)將會(huì)優(yōu)先訪(fǎng)問(wèn)類(lèi)別中的方法,將會(huì)取代初始的方法,所以最好給自己的類(lèi)別方法添加前綴。
- 和普通接口有所區(qū)別的是,在分類(lèi)的實(shí)現(xiàn)文件中可以不必實(shí)現(xiàn)所有聲明的方法,只要你不去調(diào)用它。
這樣我們可以通過(guò)將不同的方法實(shí)現(xiàn)放入不同的類(lèi)別中實(shí)現(xiàn)了代碼的分散和私有方法。
與類(lèi)拓展extension相比
類(lèi)拓展括號(hào)中不添加類(lèi)別名,可以添加實(shí)例變量。