簡體   English   中英

NSNotification addObserver:someOtherClass

[英]NSNotification addObserver:someOtherClass

我需要將一條消息傳遞給一個控制類(它會創建一個將要發送消息的類的實例)所以,我不能直接在我的文件中引用類名,而不是讓它成為一個全局(這是荒謬的如果“NSNotification”宣傳能夠傳遞所有類型的消息,無論他們在哪里/什么類。

所以沒有進一步的...

(從Say ClassB打電話)

ClassA創建ClassB的實例

現在在ClassB ,我需要將關於按鈕按下的消息傳遞回ClassA

(insdie ClassB)
- (void)viewDidLoad
{
  [[NSNotificationCenter defaultCenter] addObserver:ClassA 
                                        selector:@selector(doLoginAction)      
                                        name:@"SomeButton" 
                                        object:nil];
  [super viewDidLoad];
}

這不會編譯,即使我包括,抱歉, "#import "ClassA.h"現在,如果我做一些愚蠢的事情,

ClassA *classa = [[ClassA alloc]init];

然后在addObserver:classa使用這個新創建的addObserver:classa實例addObserver:classa它會編譯,但正如我想的那樣,絕對沒有...(我知道,但令人驚訝的是這種代碼在Iphone編程書籍中很流行......)所以無論如何我都試過了。

但是,如果我將此函數放在ClassA並使用addObserver:ClassB它將被調用,但會導致堆棧轉儲unrecognized selector sent to instance或使用addObserver:self

我很想刪除Xcode並回到vim並使用舊的“C”回調...

所以,如果我做對了,你就有了一個創建ClassB實例的ClassA 反過來,這些實例應該直接向ClassA發送通知,而不知道任何相關信息。

如果這是正確的,那么NSNotificationCenter正是您所需要的。

ClassA實現中添加一個initialialize方法,如下所示:

@implementation ClassA

+ (void)initialize
{
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(YourSelector:)
               name:@"YourNotificationName"
             object:nil];
}

+ (void)YourSelector:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];

    // ...
}

// ...

@end

然后, ClassB實例應僅使用其名稱發布其通知:

@implementation ClassB

- (void)postNotification
{
    NSDictionary *userInfo = ...;    // may be nil
    [[NSNotificationCenter defaultCenter]
        postNotificationName:@"YourNotificationName"
                               // the same name is used in the `addObserver` call
                               // in the previous code snippet
                      object:nil
                    userInfo:userInfo];
}

// ...

@end

總而言之,如果您使用的是NSNotificationCenter,則無需了解有關通知接收方的任何信息。 實際上,您可以訂閱addObserver數量的對象以接收相同的通知,並且每個對象在接收到通知對象時將調用其適當的方法(在addObserver指定)。

請記住,在將類實例添加為觀察者而不是類對象本身的情況下,應該在該實例的dealloc方法中調用[[NSNotificationCenter defaultCenter] removeObserver:self]

我在這看到幾個問題。

首先,您需要停止嘗試交替使用類和實例。 直到你有一個合理的心理模型來表明你的類和實例代表什么以及它們對你負責什么,你會對何時使用哪一個和一般的OOP產生各種各樣的困惑。

NSNotificationCenter允許您注冊類的特定實例,單個對象,作為特定通知的觀察者。 您需要了解並參考觀察對象,以便將其注冊為觀察者。

其次,您需要考慮每個類的內容,以及它們的實例化對象所負責的內容。 他們應該知道什么,他們不需要知道什么,以及他們如何溝通。

假設您將ObjectA創建為ClassA一個實例,並創建ObjectB ,它是ClassB一個實例。 現在ObjectA知道了ObjectB ,在所有A剛剛創建了B之后,A很容易對B進行引用ObjectB還沒有意識到ObjectA ; B已創建,但它不需要知道哪個對象,甚至不知道該對象是哪個類的實例。 如果您希望ObjectB能夠與ObjectA通信,您有幾個選擇。

  1. 代表團: ObjectA上設置一個屬性ObjectB重新指向ObjectA ,現在B可將消息發送給直接。 現在你的兩個對象耦合在一起,既有用也有問題。
  2. 通知: ObjectB可以發布通知, ObjectA可以觀察通知。 B不需要知道A正在觀察那些通知,並且A不需要知道通知源自B(盡管可能)。 這些對象非常松散耦合,您可以在不了解應用程序的情況下更改應用程序的許多內容。

重要的是,如果ObjectA要監聽通知,則A有責任將自己添加為觀察者。 由於B不知道A,因此B無法使A成為觀察者。 一個人的創造者可能因為那個物體會引用A,但A的孩子不能,除非他們給了A一些參考。

亞歷克斯看起來像一個很好的答案,所以希望這將是有用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM