一、概念擴充:
1、如我們所知,使用category是用來對現有類進行功能擴展,或者將類分成多模塊的一種方式。由聲明和實現兩部分組成。可以單獨寫成Objiective-C File類型文件(包含.h和.m)。
2、category可以用來給現有類添加新的方法。
3、category不可以給類添加成員,會直接報錯(編譯不過)。
4、category可以用@property來添加屬性,此種方式會自動生成對應屬性的set和get方法的聲明,但是沒有set和get方法的實現,也不會自動生成帶有“_”的屬性。
5、category添加的屬性使用點語法無效,原因如上。
二、如何實現給category添加可以使用的屬性
案例一:
1、給UIView類中添加4個屬性,用來獲得和更改控件frame的x,y,width,height。正常開發中,我們無法直接通過點語法來給一個控件的frame中x,y,width,height直接進行賦值操作,因為frame是CGRect類型的結構體,其中的兩個成員origin和 size也是結構體類型。我們通過給UIView寫一個category來實現這一操作。
(1)在category的聲明中添加4個新屬性:
#import <UIKit/UIKit.h> @interface UIView (EXTFrame) @property (nonatomic,assign) CGFloat x; @property (nonatomic,assign) CGFloat y; @property (nonatomic,assign) CGFloat width; @property (nonatomic,assign) CGFloat height; @end
(2)在category的實現中進行set和get方法的重寫:
#import "UIView+EXTFrame.h" @implementation UIView (EXTFrame) -(void)setX:(CGFloat)x { CGRect rect = self.frame; rect.origin.x=x; self.frame = rect; } -(CGFloat)x { return self.frame.origin.x; } -(void)setY:(CGFloat)y { CGRect rect = self.frame; rect.origin.y=y; self.frame=rect; } -(CGFloat)y { return self.frame.origin.y; } -(void)setWidth:(CGFloat)width { CGRect rect = self.frame; rect.size.width=width; self.frame=rect; } -(CGFloat)width { return self.frame.size.width; } -(void)setHeight:(CGFloat)height { CGRect rect = self.frame; rect.size.height=height; self.frame=rect; } -(CGFloat)height { return self.frame.size.height; }
(3)雖然category不會生成帶有“_”的屬性,並不是代表set和get不可用,創建完category后,在后面開發過程中,只要包含了category頭文件,同時繼承於UIView的類的對象,均可以直接使用點語法獲得和更改x,y,width,height,比如:MyImageView.x=50,可以非常方便的給控件的frame做改動。
案例二:
1、給UIView類添加name屬性,通過關聯對象(運行時機制)增加屬性。
運行時實現功能:
———>運行時能夠給正在運行的對象添加屬性。
———>運行時能夠獲取正在運行的對象的所有屬性。
———>運行時能夠用來交換方法。
(1)在category的聲明中添加name屬性:
#import <UIKit/UIKit.h> @interface UIView (EXTName) @property(nonatomic,copy) NSString * name; @end
(2)在category的實現中通過運行時重寫屬性的set和get,要求包含objc框架里的runtime.h頭文件。
#import "UIView+EXTName.h" #import <objc/runtime.h> @implementation UIView (EXTName) -(void)setName:(NSString *)name { //self表示正在運行的對象,“NAME”是C的標識,name為添加的新屬性的值,最后一個參數是屬性修飾符(枚舉) objc_setAssociatedObject(self, "NAME", name, OBJC_ASSOCIATION_COPY_NONATOMIC ); } -(NSString *)name { return objc_getAssociatedObject(self, "NAME"); } @end
(3)添加完此category后,UI控件可以通過點語法直接訪問和設置“name”屬性。