5、通知和代理區別和使用

一、代理Delegate

1.使用的場合

主要用於子控件發生某些動作時,通知父控件,子控件的代理是父控件。常見就控制器就是子控件的的代理。

2.代理的使用步驟

1> 先搞清除誰是誰的代理
2> 定義代理協議,協議名稱的規範是:控件類名+Delegate
3> 定義代理方法
    *代理方法一般都定義@optional
    *代理方法名都以控件名開頭
    *代理方法至少一個參數,將控件本身傳遞出去
4> 設置代理對象
    *代理對象遵守協議
    *代理對象實現協議裏面的該實現的方法
5> 在恰當的時候調用代理對象的代理方法,通知代理髮生了什麼事

用法:
1.系統定義好的代理:UITableViewDelegate
使用步驟:

1> 遵守代理協議
2> 實現協議的方法就行了(運行循環,監聽代理的動作)

2.自定義的代理
在A中定義代理

A.h文件
// 前向引用
@class A;
@protocol aDelegate <NSObject>

@optional
/**
 *  代理方法
 */
- (void)aXXX:(A*)a;

@end
@interface A : NSObject
/**
 *  代理屬性
 */
@property(nonatomic,weak) id <aDelegate> delegate;

@end

A.m文件

@implementation A
/**
 *  A發生某些事情,在xxx方法中通知代理B執行代理的操作
 */
- (void) xxx
{
    if ([self.Delegate respondsToSelector:@selector(aXXX:)]) {
        [self.Delegate aXXX:self];
    }
}
@end

B.m

#import "A.h"
@interface B <aDelegate>
@end

@implementation B

/**
 *  因爲總部A發生事情執行了xxx方法,在xxx方法中通知代理B執行aXXX方法
 *
 *  @param a <#a description#>
 */
- (void) aXXX:(A*)a
{
    //操作某些事情
}

@end

二、通知(NSNotification)

1.通知的屬性

// 通知的名稱
@property (readonly, copy) NSString *name;
// 通知的發佈者
@property (readonly, retain) id object;
// 一些額外的信息
@property (readonly, copy) NSDictionary *userInfo;

2.初始化一個通知對象

- (instancetype)initWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo
+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject;
+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

3.發佈通知

- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

4.註冊通知監聽器
1>

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
//  observer:監聽器
//  aSelector:收到通知後回到的方法,把通知對象當做參數傳入
//  aName:通知的名字,爲nil,無論通知名稱是什麼,監聽器都能接受到這個通知
//  anObject:通知的發佈者,anObject和name 都爲nil,監聽器能收到所有的通知

2>

- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block;
//  name:通知的名稱
//  obj:通知的發佈者
//  block:收到對應的通知時,會回到的這個block
//  queue:決定block在那個隊列中執行

5.註銷通知監聽器

- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;

通知中心不會保留監聽器對象,在通知中心註冊過的對象,必須在該對象釋放前取消註冊,否則相應的通知再次出現時,通知中心仍然會向監聽器對象發送通知,相應的監聽器已經不存在了,可能會導致應用崩潰

一般的用法:

// 監聽通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changetext) name:UITextFieldTextDidChangedNotification object:self.accoutField];

// 接受到通知後執行的操作
- (void)changetext{}

// 移除監聽
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

三、UIDevice通知

// 可以獲得單例對象
 [UIDevice currentDevice];

發佈通知的名稱常量

// 設備旋轉
UIDeviceOrientationDidChangeNotification 
// 電池狀態改變
UIDeviceBatteryStateDidChangeNotification 
// 電池電量改變
UIDeviceBatteryLevelDidChangeNotification
// 近距離傳感器(比如設備貼近了使用者的臉部) 
UIDeviceProximityStateDidChangeNotification 

四、鍵盤通知

1.特定的通知

// 鍵盤即將顯示
UIKeyboardWillShowNotification 
// 鍵盤顯示完畢
UIKeyboardDidShowNotification 
// 鍵盤即將隱藏
UIKeyboardWillHideNotification 
// 鍵盤隱藏完畢
UIKeyboardDidHideNotification 
// 鍵盤的位置尺寸即將發生改變
UIKeyboardWillChangeFrameNotification 
// 鍵盤的位置尺寸改變完畢
UIKeyboardDidChangeFrameNotification 

2.鍵盤通知的額外信息

// 鍵盤剛開始的frame
UIKeyboardFrameBeginUserInfoKey 
// 鍵盤最終的frame(動畫執行完畢後)
UIKeyboardFrameEndUserInfoKey 
// 鍵盤動畫的時間
UIKeyboardAnimationDurationUserInfoKey 
// 鍵盤動畫的執行節奏(快慢)
UIKeyboardAnimationCurveUserInfoKey

補充:

通知和代理的選擇

1.共同點:都能完成對象之間的通信
2.不同點:
* 代理:一對一的關係
* 通知:多對多的關係
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章