首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS NSNotificationCenter 傳遞自定義對象的完整流程

     編輯:程式設計綜合問答

在 iOS 中使用 NSNotificationCenter 進行跨組件通信時,正確傳遞自定義對象(如 MyAccount)需要遵循標準流程:註冊觀察者、發送通知、接收處理。

完整實現步驟

1. 定義通知名稱常量(推薦)

// 全局常量文件或相關類別中
static NSString *const kDidLoginNotification = @"com.myapp.didLogin";

2. 添加觀察者(接收方)

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleLoginNotification:)
                                                 name:kDidLoginNotification
                                               object:nil];
}

- (void)dealloc {
    // 關鍵:移除觀察者防止崩潰與記憶體洩漏
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

3. 處理通知的方法

- (void)handleLoginNotification:(NSNotification *)notification {
    // 從 notification.object 獲取傳遞的對象
    MyAccount *account = (MyAccount *)notification.object;
    
    // 也可從 userInfo 獲取字典數據
    // NSDictionary *userInfo = notification.userInfo;
    
    if (account) {
        // 更新 UI、儲存數據等
        NSLog(@"用戶登入:%@", account.username);
    }
}

4. 發送通知(發送方)

- (void)loginSuccessWithAccount:(MyAccount *)account {
    // 業務邏輯...
    
    // 發送通知,將 account 作為 object 傳遞
    [[NSNotificationCenter defaultCenter] postNotificationName:kDidLoginNotification
                                                        object:account
                                                      userInfo:nil];
}

關鍵注意事項

通知名稱必須完全一致

註冊時的 name 與發送時的 postNotificationName: 必須是同一個字串對象,建議使用常量定義。

處理方法簽名固定

Selector 對應的方法必須接受單一 NSNotification * 參數:

// 正確
- (void)handleNotification:(NSNotification *)notification;

// 錯誤:無法直接接收自定義對象
- (void)handleNotification:(MyAccount *)account; // 不會被調用

線程安全

  • 通知在發送線程同步分發給觀察者
  • 若需在主線程處理 UI,請在處理方法中分發:
- (void)handleLoginNotification:(NSNotification *)notification {
    dispatch_async(dispatch_get_main_queue(), ^{
        MyAccount *account = (MyAccount *)notification.object;
        // 更新 UI
    });
}

記憶體管理

  • ARC 環境下 notification.object 不會自動 retain,若需持有請自行 retain/copy
  • 必須在 dealloc 或 viewDidDisappear 中移除觀察者

進階:使用 block 觀察者(iOS 4+)

id observer = [[NSNotificationCenter defaultCenter] 
    addObserverForName:kDidLoginNotification
                object:nil
                 queue:[NSOperationQueue mainQueue]
            usingBlock:^(NSNotification *note) {
    MyAccount *account = (MyAccount *)note.object;
    // 自動在主隊列執行,適合 UI 更新
}];

// 移除時需保存 observer 令牌
[[NSNotificationCenter defaultCenter] removeObserver:observer];

替代方案對比

方案適用場景耦合度
NotificationCenter多對多、跨模組、無直接引用低
Delegate 代理一對一、明確所有權關係中
Block/Closure 回調簡單異步回調低
KVO屬性變化觀察中
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved