????????Catrgory & Extension
- Category 給原有的類擴展特有的方法;
- Extension 可以擴展變量、屬性,可以改寫屬性的讀寫屬性。
- 什么時候使用?
注意,下面的代碼示例是在 BLDemo2 當中進行的,即dragonView
??如何給類擴充方法呢(自己創建的類,可以直接在里面創建方法很方便。一般使用 Category 都是給看不到源碼的庫),新創建一個OC文件,類型為 Category ,這里命名為 URL,Class 這里選擇 NSString 。
??創建出來之后它的命名方式很獨特,首先由 .h 和 .m 文件,其次名稱是 NSString+URL 。 在新創建的類中創建一個例子(僅僅是舉例), .h 文件中:
#import <Foundation/Foundation.h>
@interface NSString (URL)
- (BOOL)isURL;
@end
??在 .m 文件中寫明方法:
#import "NSString+URL.h"
@implementation NSString (URL)
- (BOOL)isURL
{
if ([self hasPrefix:@"http://"]) {
return YES;
}
return NO;
}
@end
??如果以后真的需要判斷是不是URL,這樣的方法是不行的,還需要通過比如使用正則表達式等方法。
??接下來嘗試使用 Category 添加的方法,在 ViewController.m 中先導入 #import "NSString+URL.h":
- (void)viewDidLoad {
[super viewDidLoad];
NSString *url = @"www.baidu.com";
if ([url ifURL]) {
NSLog(@"是一個網址");
} else {
NSLog(@"不是一個網址");
}
}
??關于 Extension 增加成員變量就更佳地方便,可以直接在 ViewController.m 中操作:
@interface ViewController ()
{
BLDragonView *_dragonView1;
}
// 增加屬性就是這樣操作
@property(nonatomic, retain)BLDragonView *dragonView;
@end
??這樣的好處是在 ViewController 這個類中可以在任何地方對 _dragonView1 進行訪問。
??關于 Extension 改寫屬性的讀寫屬性,比如在你在一個類的 頭文件聲明了一個 NSString 類型的變量,并且只是具有 readonly 的特性,對外開發,但是后來你又希望把它改成對內可讀寫的,這時就可以在實現文件中通過 Extension 改變它的屬性。
????????NSNotification
- 什么是通知?
??當發生某件事情之后,將消息發送給所有的對象,對象收到通知后,就會進行相應的操作。代理 “主要” 是一對一的形式,通知一般為1對多。 - 什么時候用?
- 怎么用?
??通知的例子可以在 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];
// 通知類頭一個通知中心,固定在此處發送信息
// 使用異步線程處理通知,在通知多并且希望不阻塞主線程的情況下
[[NSNotificationQueue defaultQueue] enqueueNotification:notification
postingStyle:NSPostNow
coalesceMask:NSNotificationNoCoalescing // 合并類型意思是用什么方式將多個通知合并到一個通知,老師推薦是不合并
forModes:nil] // 模式一般傳nil
}
??如上通知就發送出去了,現在需要有類來接收通知,我們讓 ViewController 類來接收,在 .m 文件中:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self //添加一個觀察者 由我自己來檢測這個通知
selector:@selector(receiveDragonViewNotification:) // 收到這個通知之后我該做什么
name:@“BLDragonViewNotification:” // 通知的名字,注意這個名字一定是你發出的通知的名字,一一匹配
object:nil // 意思是要接哪一個對象的通知, 如果是接所有對象的話,就填 nil
}
// 然后需要實現接收到通知后的方法
- (void)receiveDragonViewNotification:(NSNotification *)notification
{
NSDictionary *userInfo = notification.userInfo;
NSLog(@"time is %@", [userInfo valueForKey:@"time"]);
}
......
??然后運行應用后,點擊前進按鈕,就會發出通知, ViewController 類酒會接收到通知,然后打印出 key “time” 的鍵值。
??為了顯示通知一對多的特性,我們可以將接收通知在別的類中實現,然后實現相應的接收到通知后的方法。
??需要注意的一點是,因為接收監聽是系統方法,當 ViewController 類被釋放之后,這個監聽還是沒有被釋放,并且類沒有了就收不到信息了,這樣應用繼續運行是會導致崩潰的。一般這時,就會運用到 dealloc 方法。如何移出通知呢?在 ViewController.m 中:
- (void)dealloc
{
// [[NSNotificationCenter defaultCenter] removeObserver:self name: object:(id)]; 因為一般這個類中或許需要監聽很多,所以方便效率起見,會刪除所有,會如下:
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
??一定需要注意和掌握這個方法,很多初學者都會只設置監聽,卻不移除,就會有可能在以后造成應用的崩潰。
??還需要注意,通知的發出嗬監聽是同步的,意思就是例如當你發出非常多的通知,很多類就會一個一個地去監聽,做不了其他事情,如果接受完畢需要10分鐘,就代表將阻塞主線程10分鐘。(有時候應用用著用著就不動了,這很有可能就是主線程被阻塞掉了)所以當你有非常多的通知需要發送時,盡量不要在主線程中使用,使用異步的方法(看第五個代碼段最下面的代碼)。最后的效果是一樣的,就是不會造成阻塞主線程,一般情況下會使用post,根據具體情況選擇。
OC語法完成,ok!(后續學習查漏補缺~)