iOS之category深入理解

引用:

無論一個類設計的多么完美,在未來的需求演進中,都有可能會碰到一些無法預測的情況。那怎么擴展已有的類呢?一般而言,繼承和組合是不錯的選擇。但是在Objective-C 2.0中,又提供了category這個語言特性,可以動態(tài)地為已有類添加新行為。如今category已經遍布于Objective-C代碼的各個角落,從Apple官方的framework到各個開源框架,從功能繁復的大型APP到簡單的應用,catagory無處不在

兩種類型:

  • 1
    eg:著名的MJRefresh
普通的分類.png
  • 2 class-continuation 分類(其實不能算是分類,緊緊是private的作用)

eg:

注意事項:

  • 命名:如果分類方法的命名和類中方法名相同則實際是覆蓋(并不是真正意義上的覆蓋,詳情可以看文章末尾推薦的文章)了類中的方法,所以命名很重要,如著名的SDWebImage UIImageView的分類 方法名均以sd_打頭


    SDWebImage.png
  • 實例變量可以放到class-continuation 分類中,也可以放到實現文件中,個人建議放到
    class-continuation 分類,因為和私有屬性、方法放一起會更清晰一些

作用:

  1. 她可以為任何類添加新的方法,包括那些沒有源代碼的類,無需創(chuàng)建對象類的子類就能完成同樣的工作
  2. 將類的實現代碼分散到便于管理的數個分類中,這樣會清晰很多
  3. 便于調試,call stack(回溯信息中)查看較方便
  4. 私有方法放入class-continuation 分類中隱藏細節(jié)(雖然不是真正的私有但是這樣做是可以隱藏很多不需要調用人知道的細節(jié))
  5. 關聯對象 (MJRefresh就是這樣做的)可參考iOS之category
  6. 屬性:只讀狀態(tài)可以擴充為可讀寫 不直接訪問實例變量 而是通過設置方法訪問來做 因為這樣可以觸發(fā)KVO,外部既不能修改,內部又可以按需求管理數據

下面寫個demo具體解釋,還是以Student類為例

@interface Student : NSObject

@property (nonatomic,copy,readonly) NSString *firstName;  // 這里設為只讀,不想外部改動
@property (nonatomic,copy,readonly) NSString *lastName;

- (instancetype)initWithFirstName:(NSString*)firstName lastName:(NSString*)lastName;

@end


#import "Student.h"

@interface Student()

@property (nonatomic,copy,readwrite) NSString *firstName;
@property (nonatomic,copy,readwrite) NSString *lastName;

// 這邊可以寫方法原型,方法的聲明
- (void)p_do1;
- (void)p_do2;
- (void)p_do3;

@end

@implementation Student

#pragma mark -  life circle
- (instancetype)initWithFirstName:(NSString*)firstName lastName:(NSString*)lastName {
    if (self = [super init]) {
        _firstName = [firstName copy];
        _lastName = [lastName copy];
    }
    return self;
}

- (void)dealloc {
    NSLog(@"%s",__func__);
}

#pragma mark -  public method

#pragma mark -  private method
- (void)p_do1 {
    self.firstName = @"john";
}

- (void)p_do2 {

}

- (void)p_do3 {

}

@end
@interface Student (Study)

- (void)ttt_study;
- (void)ttt_studyEnglish;

@end


#import "Student+Study.h"

@implementation Student (Study)

- (void)ttt_study {
    
}

- (void)ttt_studyEnglish {
    // 這里故意寫一個數組越界的情況為了解釋分類調試方便
    NSArray* arr = @[];
    NSObject* obj = arr[1];
    NSLog(@"study english");
}

@end
@interface Student (Play)

- (void)ttt_play;
- (void)ttt_playLOL;

@end

Play的實現就不粘上來了

如上所示:

  1. Student類有兩個屬性均為只讀,還有一個快捷初始化方法,在實現文件中我們將兩個只讀屬性擴展為可讀可寫這樣就可以調用其set方法,觸發(fā)KVO
  2. 我這邊創(chuàng)建了兩個Student分類,如果Student類的方法非常龐大,我們就可以以這種方式將各個不同功能的方法進行分類,減小文件大小使類更加清晰;方法名均已ttt打頭,這是為了避免與原類中方法重名導致覆蓋,也借鑒了優(yōu)秀代碼SDWebImage的命名習慣
  3. 我在 class-continuation 分類聲明了三個方法,以p_打頭是為了告訴自己,這是一個私有方法,當然也可以不用先聲明,直接實現即可,但是這種方式讓我隔斷時間再次看這樣的類的時候就會很快明白這個類是要干嘛的
  4. 關于調試:使用分類可以更快速的定位到錯誤,上面例子中的call stack
極力推薦:

深入理解Objective-C:Category


希望會給大家?guī)韼椭?O(∩_∩)O

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 轉至元數據結尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 2,032評論 0 9
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,628評論 18 399
  • 第四章 協(xié)議與分類 Objective-C的“協(xié)議”(protocol)與java的“接口”類似。Objectiv...
    Code_Ninja閱讀 794評論 0 2
  • 【劉遠莎:有個律師朋友是怎樣一種體驗?】 劉遠莎法律讀品 1、當你把他介紹給你的小伙伴時,大家會在第一時間認定:他...
    小好閱讀 622評論 0 4
  • 汪秋水者,德惠之先輩詩人也。邇來《梅林三友集》付梓,始見稱于州縣,詩望有歸。予既慰其揚名,復嘆其沒世,乃作此傳云。...
    金橘對芙蓉閱讀 548評論 0 1

友情鏈接更多精彩內容