16、類別、擴(kuò)展與通知

????????Catrgory & Extension

  • Category 給原有的類擴(kuò)展特有的方法;
  • Extension 可以擴(kuò)展變量、屬性,可以改寫(xiě)屬性的讀寫(xiě)屬性。
  • 什么時(shí)候使用?

注意,下面的代碼示例是在 BLDemo2 當(dāng)中進(jìn)行的,即dragonView
??如何給類擴(kuò)充方法呢(自己創(chuàng)建的類,可以直接在里面創(chuàng)建方法很方便。一般使用 Category 都是給看不到源碼的庫(kù)),新創(chuàng)建一個(gè)OC文件,類型為 Category ,這里命名為 URL,Class 這里選擇 NSString 。

category.jpg

??創(chuàng)建出來(lái)之后它的命名方式很獨(dú)特,首先由 .h 和 .m 文件,其次名稱是 NSString+URL 。 在新創(chuàng)建的類中創(chuàng)建一個(gè)例子(僅僅是舉例), .h 文件中:

#import <Foundation/Foundation.h>

@interface NSString (URL)

- (BOOL)isURL;

@end

??在 .m 文件中寫(xiě)明方法:

#import "NSString+URL.h"

@implementation NSString (URL)

- (BOOL)isURL
{
    if ([self hasPrefix:@"http://"]) {
        return YES;
    }

    return NO;
}

@end

??如果以后真的需要判斷是不是URL,這樣的方法是不行的,還需要通過(guò)比如使用正則表達(dá)式等方法。
??接下來(lái)嘗試使用 Category 添加的方法,在 ViewController.m 中先導(dǎo)入 #import "NSString+URL.h":

- (void)viewDidLoad {
    [super viewDidLoad];

    NSString *url = @"www.baidu.com";
    if ([url ifURL]) {
        NSLog(@"是一個(gè)網(wǎng)址");
    } else {
        NSLog(@"不是一個(gè)網(wǎng)址");
    }
}

??關(guān)于 Extension 增加成員變量就更佳地方便,可以直接在 ViewController.m 中操作:

@interface ViewController ()
{
    BLDragonView *_dragonView1;
}

// 增加屬性就是這樣操作
@property(nonatomic, retain)BLDragonView *dragonView;    


@end

??這樣的好處是在 ViewController 這個(gè)類中可以在任何地方對(duì) _dragonView1 進(jìn)行訪問(wèn)。
??關(guān)于 Extension 改寫(xiě)屬性的讀寫(xiě)屬性,比如在你在一個(gè)類的 頭文件聲明了一個(gè) NSString 類型的變量,并且只是具有 readonly 的特性,對(duì)外開(kāi)發(fā),但是后來(lái)你又希望把它改成對(duì)內(nèi)可讀寫(xiě)的,這時(shí)就可以在實(shí)現(xiàn)文件中通過(guò) Extension 改變它的屬性。


????????NSNotification

  • 什么是通知?
    ??當(dāng)發(fā)生某件事情之后,將消息發(fā)送給所有的對(duì)象,對(duì)象收到通知后,就會(huì)進(jìn)行相應(yīng)的操作。代理 “主要” 是一對(duì)一的形式,通知一般為1對(duì)多。
  • 什么時(shí)候用?
  • 怎么用?

??通知的例子可以在 BLDragonView.m 中操作:

- (void)forwardButtonClicked:(id)sender
{
    .......
    
    NSDictionary *dic = @{@"name":@"123456", @"time":@"08:30"};
    NSNotification *notification = [[NSNotification alloc] initWithName:@"BLDragonViewNotification"
                                                                 object:nil
                                                                   user:dic];
    [[NSNotificationCenter defaultCenter] postNotification:notification];
     // 通知類頭一個(gè)通知中心,固定在此處發(fā)送信息

    // 使用異步線程處理通知,在通知多并且希望不阻塞主線程的情況下
    [[NSNotificationQueue defaultQueue] enqueueNotification:notification
                                               postingStyle:NSPostNow
                                               coalesceMask:NSNotificationNoCoalescing        // 合并類型意思是用什么方式將多個(gè)通知合并到一個(gè)通知,老師推薦是不合并
                                                   forModes:nil]    // 模式一般傳nil
}

??如上通知就發(fā)送出去了,現(xiàn)在需要有類來(lái)接收通知,我們讓 ViewController 類來(lái)接收,在 .m 文件中:

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self     //添加一個(gè)觀察者  由我自己來(lái)檢測(cè)這個(gè)通知
                                             selector:@selector(receiveDragonViewNotification:)         // 收到這個(gè)通知之后我該做什么
                                                 name:@“BLDragonViewNotification:”         // 通知的名字,注意這個(gè)名字一定是你發(fā)出的通知的名字,一一匹配
                                               object:nil       // 意思是要接哪一個(gè)對(duì)象的通知,  如果是接所有對(duì)象的話,就填 nil
}

// 然后需要實(shí)現(xiàn)接收到通知后的方法
- (void)receiveDragonViewNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = notification.userInfo;
    NSLog(@"time is %@", [userInfo valueForKey:@"time"]);
}
......

??然后運(yùn)行應(yīng)用后,點(diǎn)擊前進(jìn)按鈕,就會(huì)發(fā)出通知, ViewController 類酒會(huì)接收到通知,然后打印出 key “time” 的鍵值。
??為了顯示通知一對(duì)多的特性,我們可以將接收通知在別的類中實(shí)現(xiàn),然后實(shí)現(xiàn)相應(yīng)的接收到通知后的方法。
??需要注意的一點(diǎn)是,因?yàn)榻邮毡O(jiān)聽(tīng)是系統(tǒng)方法,當(dāng) ViewController 類被釋放之后,這個(gè)監(jiān)聽(tīng)還是沒(méi)有被釋放,并且類沒(méi)有了就收不到信息了,這樣應(yīng)用繼續(xù)運(yùn)行是會(huì)導(dǎo)致崩潰的。一般這時(shí),就會(huì)運(yùn)用到 dealloc 方法。如何移出通知呢?在 ViewController.m 中:

- (void)dealloc
{
    // [[NSNotificationCenter defaultCenter] removeObserver:self name: object:(id)];   因?yàn)橐话氵@個(gè)類中或許需要監(jiān)聽(tīng)很多,所以方便效率起見(jiàn),會(huì)刪除所有,會(huì)如下:
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

??一定需要注意和掌握這個(gè)方法,很多初學(xué)者都會(huì)只設(shè)置監(jiān)聽(tīng),卻不移除,就會(huì)有可能在以后造成應(yīng)用的崩潰。
??還需要注意,通知的發(fā)出嗬監(jiān)聽(tīng)是同步的,意思就是例如當(dāng)你發(fā)出非常多的通知,很多類就會(huì)一個(gè)一個(gè)地去監(jiān)聽(tīng),做不了其他事情,如果接受完畢需要10分鐘,就代表將阻塞主線程10分鐘。(有時(shí)候應(yīng)用用著用著就不動(dòng)了,這很有可能就是主線程被阻塞掉了)所以當(dāng)你有非常多的通知需要發(fā)送時(shí),盡量不要在主線程中使用,使用異步的方法(看第五個(gè)代碼段最下面的代碼)。最后的效果是一樣的,就是不會(huì)造成阻塞主線程,一般情況下會(huì)使用post,根據(jù)具體情況選擇。


OC語(yǔ)法完成,ok!(后續(xù)學(xué)習(xí)查漏補(bǔ)缺~)

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容