分類(Category
)是OC中的特有語法,它是表示一個指向分類的結構體的指針。原則上它只能增長方法,不能增長成員(實例)變量。markdown
爲已經存在的類添加方法。能夠在不修改原來類的基礎上,爲一個類 擴展方法。最主要的應用:給系統自帶的類 擴展方法。this
1.分類中只能添加「方法」,不能增長成員變量。分類中的能夠寫@property
, 但不會生成setter/getter
方法, 也不會生成實現以及私有的成員變量,會編譯經過,可是引用變量會報錯。spa
2.分類中能夠/只能
訪問原有類中.h中的屬性。若是想要訪問本類中的私有變量,分類和子類同樣,只能經過方法來訪問。ssr
3.在本類和分類有同名方法時,優先調用分類的方法
。同名方法調用的優先級爲分類 > 本類 > 父類
。3d
4.若是多個分類中都有和原有類中同名的方法,那麼調用該方法的時候執行誰由編譯器決定;編譯器會執行最後一個參與編譯
的分類中的方法。指針
分類方法不會覆蓋掉原來類中的方法,而是共存的。可是分類中的方法在前面,原來的類中的方法在後面,調用的時候,就會調用分類中的方法,若是多個分類有一樣的方法,後編譯的分類會調用。code
例如,建立一個UIView的分類:orm
在新建的文件的.h中聲明新方法,在.m中具體實現方法 格式:對象
@interface 待擴展類的類名(分類名字)
/*方法聲明*/
@end
@implementation 待擴展類的類名(分類名字)
/*方法實現*/
@end
複製代碼
編譯完以後每個分類都會生成一個結構體category_t
,裏面存儲着分類的對象方法、類方法、屬性、協議信息。在程序運行的時候,runtime會將Category的數據,合併到類信息中(類對象、元類對象中)繼承
struct category_t {
const char *name;
classref_t cls;
struct method_list_t *instanceMethods;
struct method_list_t *classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};
複製代碼
.h中
#import <UIKit/UIKit.h>
@interface UIImage (Size)
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize ;
@end
複製代碼
.m中
#import "UIImage+Size.h"
@implementation UIImage (Size)
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end
複製代碼
1.類擴展(extension
)是Category
的一個特例,有時候也被稱爲匿名分類。他的做用是爲一個類添加一些私有的成員變量和方法。 2.和分類不一樣,類擴展便可以聲明成員變量又能夠聲明方法。 3.分類的小括號中必須有名字
Class Extension
在編譯的時候,它的數據就已經包含在類信息中。 Category
是在運行時,纔會將數據合併到類信息中。
有load方法,load方法在runtime加載類、分類的時候調用。load方法能夠繼承,可是通常狀況下不會主動去調用load方法,都是讓系統自動調用。