iOS學習筆記2(結合專案)--Category和Extension的區別

jingxianli0922發表於2015-11-02

在實際專案中,用到Category比較多,Category也很實用,我們可以把一些經常用到或者很通用的功能封裝到一個Category裡,當其他專案需要相同的功能時,我們可以直接拿來用,不用從零開始寫,可以提高專案的開發效率。下面我將重點講解Category:

1.Category是什麼?

Category用於向已經存在的類新增方法從而達到擴充套件已有類的目的,在很多情形下Category也是比建立子類更優的選擇,新新增的方法同樣也會被被擴充套件的類的所有子類自動繼承。當知道已有類中某個方法有BUG,但是這個類是以庫的形式存在的,我們無法直接修改原始碼的時候,Category也可以用於替代這個已有類中某個方法的實體,從而達到修復BUG的目的。然而卻沒有什麼便捷的途徑可以去呼叫已有類中原有的那個被替換掉方法實體了。Category通常作為一種組織框架程式碼的工具來使用。

2.Category的用途
    1.  在不建立繼承類的情況下實現對已有類的擴充套件。
    2.  簡化類的開發工作(當一個類需要多個程式設計師協同開發的時候,Category可以將同一個類根據用途分別放在不同的原始檔中,從而便於程式設計師獨立開發相應的方法集合)。
    3.  將常用的相關方法進行分組。
    4.  在沒有原始碼的情況下可以用來修復BUG。

3.Category的用法

建立一個iOS Single View Applciation名為CategoryExample。然後為建立一個NSString類的category擴充套件。File->New->File然後選擇 Cocoa Touch Objective-C category命名為jwl,Category on NSDate,如下圖所示:


系統會自動生成一個固定格式NSDate+jwl的.h和.m檔案。

宣告Category

開啟NSDate+jwl檔案,在裡面新增如下程式碼:

//
//  NSDate+jwl.h
//  JWeiBo
//
//  Created by bcc_cae on 15-9-29.
//  Copyright (c) 2015年 bcc_cae. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSDate (jwl)


/**
 * 判斷某個時間是否為今天
 */
-(BOOL)isToday;
/**
 * 判斷某個時間是否為昨天
 */
-(BOOL)isYesterday;
/**
 * 判斷某個時間是否為今年
 */
-(BOOL)isYear;
/**
 * 將某個時間格式化為yyyy-MM-dd
 */
-(NSDate *)dateWithYMD;
/**
 * 計算某個時間與當前時間的時間差
 */
-(NSDateComponents *)deltaWithNow;


@end

實現Category

開啟NSDate+jwl.m檔案,在裡面新增如下程式碼:

//
//  NSDate+jwl.m
//  JWeiBo
//
//  Created by bcc_cae on 15-9-29.
//  Copyright (c) 2015年 bcc_cae. All rights reserved.
//

#import "NSDate+jwl.h"


@implementation NSDate (jwl)

/**
 * 判斷某個時間是否為今天
 */
-(BOOL)isToday
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    int unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    
    //1.獲得當前時間的年月日
    NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
    
    //2.獲得self的年月日
    NSDateComponents *selfCmps = [calendar components:unit fromDate:self];
    
    return nowCmps.year == selfCmps.year && nowCmps.month == selfCmps.month && nowCmps.day == selfCmps.day;
}

/**
 * 判斷某個時間是否為昨天
 */
-(BOOL)isYesterday
{
    NSDate *nowDate = [[NSDate date] dateWithYMD];
    NSDate *selfDate = [self dateWithYMD];
    //獲得nowDate和selfDate的差距
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *cmps = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0];
    return cmps.day == 1;
    
}

/**
 * 判斷某個時間是否為今年
 */
-(BOOL)isYear
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    int unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    
    //1.獲得當前時間的年月日
    NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
    
    //2.獲得self的年月日
    NSDateComponents *selfCmps = [calendar components:unit fromDate:self];
    
    return nowCmps.year == selfCmps.year;
}

/**
 *  計算某個時間與當前時間的時間差
 */
-(NSDateComponents *)deltaWithNow
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    int unit = NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    return [calendar components:unit fromDate:self toDate:[NSDate date] options:0];
}


/**
 *  將某個時間格式化為yyyy-MM-dd
 *
 *  @return  [fmt dateFromString:str]
 */
-(NSDate *)dateWithYMD
{
    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    fmt.dateFormat = @"yyyy-MM-dd";
    NSString *str = [fmt stringFromDate:self];
    return  [fmt dateFromString:str];
}

@end</span>

Category能對大型類有效分解。通常一個大型類的方法可以根據某種邏輯或是相關性分解為不同的組,一個類的程式碼量越大,將這個類分解到不同的檔案中就顯得越有用,每個檔案中分別是這個類的某些相關方法的集合。當有多個開發者共同完成一個專案時,每個人所承擔的是單獨的cagegory的開發和維護。這樣就版本控制就更加簡單了,因為開發人員之間的工作衝突更少了。

4.Category和Extension的區別

Category

1).不能向類新增例項變數,只能新增例項方法。

2).名稱衝突。類別具有更高優先順序,當類別方法名與原始類方法名相同時,類別方法將覆蓋原始類方法。

3).Category新增的方法可以不實現。

Extension

1).extentsion可以新增屬性。

2).形式上看,Extension是匿名的Category。

3).extension裡宣告的方法必須實現

5.建議

如果需要新增一個新的變數,則需新增子類。

如果只是新增一個新的方法,用Category是比較好的選擇。


感謝  博友的iOS設計模式——Category 文章連結http://blog.csdn.net/lovefqing/article/details/8289851

程式碼下載地址:http://download.csdn.net/detail/jasonjwl/9238347


相關文章