OC-分類(Category)

分類(Category)是OC中的特有語法,它是表示一個指向分類的結構體的指針。原則上它只能增長方法,不能增長成員(實例)變量。markdown

Category的做用

爲已經存在的類添加方法。能夠在不修改原來類的基礎上,爲一個類 擴展方法。最主要的應用:給系統自帶的類 擴展方法。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);
};
複製代碼

案例

UIImage的分類,添加擴展方法更改圖片大小。

.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
複製代碼

分類(Category)和類擴展(extension)的關係

1.類擴展(extension)是Category的一個特例,有時候也被稱爲匿名分類。他的做用是爲一個類添加一些私有的成員變量和方法。 2.和分類不一樣,類擴展便可以聲明成員變量又能夠聲明方法。 3.分類的小括號中必須有名字

Class Extension在編譯的時候,它的數據就已經包含在類信息中。 Category是在運行時,纔會將數據合併到類信息中。

其餘

  • Category中有load方法嗎?

有load方法,load方法在runtime加載類、分類的時候調用。load方法能夠繼承,可是通常狀況下不會主動去調用load方法,都是讓系統自動調用。

相關文章
相關標籤/搜索