2013-07-27 122 views
1

我的應用程序中有一個設置面板。無論何時用戶按下按鈕,隨着UI更新,該對象將在另一個線程上更新。我在主視圖上有一個單獨的標籤,當對象完成更新時(我想要發生而不管設置面板是打開還是關閉),應該更新對象計數。我試着按照apple documentation regarding this very topic,但它似乎並沒有爲我工作 - 也就是說,主視圖控制器似乎從來沒有收到通知出於某種原因。有沒有人有任何建議如何警告主視圖控制器傳遞給另一個線程的對象已完成更新?下面是我使用的代碼(其中大部分是從那個文件夾複製):從另一個線程發送通知

對象類:

[[NSNotificationCenter defaultCenter] postNotificationName: @"ScaleCountUpdated" object: self]; 

主視圖控制器

- (void)setUpThreadingSupport 
{ 
    if (self.notifications) { 
     return; 
    } 
    self.notifications = [[NSMutableArray alloc] init]; 
    self.notificationLock = [[NSLock alloc] init]; 
    self.notificationThread = [NSThread currentThread]; 

    self.notificationPort = [[NSMachPort alloc] init]; 
    [self.notificationPort setDelegate: self]; 
    [[NSRunLoop currentRunLoop] addPort: self.notificationPort 
          forMode: (NSString *)kCFRunLoopCommonModes]; 
} 

- (void)handleMachMessage:(void *)msg 
{ 
    [self.notificationLock lock]; 

    while ([self.notifications count]) { 
     NSNotification *notification = [self.notifications objectAtIndex: 0]; 
     [self.notifications removeObjectAtIndex: 0]; 
     [self.notificationLock unlock]; 
     [self processNotification: notification]; 
     [self.notificationLock lock]; 
    }; 

    [self.notificationLock unlock]; 
} 

- (void)processNotification:(NSNotification *)notification{ 

    if ([NSThread currentThread] != self.notificationThread) { 
     // Forward the notification to the correct thread. 
     [self.notificationLock lock]; 
     [self.notifications addObject: notification]; 
     [self.notificationLock unlock]; 
     [self.notificationPort sendBeforeDate: [NSDate date] 
            components: nil 
             from: nil 
            reserved: 0]; 
    } else { 
     [self updateScaleCount]; 
    } 
} 

- (void)updateScaleCount 
{ 
    NSLog(@"[ScalesViewController - updateScaleCount]: Scales updated from notification center."); 
    if([UserDefinedScales areScalesGrouped] == YES){ 
     self.groupCountLabel.text = [NSString stringWithFormat: @"Group Count: %i", [[UserDefinedScales sortedKeys] count]]; 
    } else { 
     self.groupCountLabel.text = @"Group Count: 1"; 
    } 
    self.scaleCountLabel.text = [NSString stringWithFormat: @"Scale Count: %i", [UserDefinedScales scaleCount]]; 
} 

主視圖控制器 - 查看加載:

[self setUpThreadingSupport]; 
    [[NSNotificationCenter defaultCenter] addObserver: self 
              selector: @selector(processNotification:) 
               name: @"ScaleCountUpdated" 
               object: nil]; 

如果您有任何關於如何修改此代碼以使其正常工作的建議,或者有其他解決方案來實現此目的,我們將不勝感激!謝謝。

回答

0

它看起來像我這樣做是正確的,即註冊通知併發送它。

就我所見,從您的代碼和您提供的信息中,您基本上可以完全忘記setupThreadingSupport。沒有它你一定要測試它。不知道你想達到什麼,但看起來像是過度殺傷,可能只是一個簡單的塊就足夠了。是否有令人信服的理由在後臺線程上收聽通知?爲什麼不讓通知中心決定?

記錄發送和接收通知 - addObserverpostNotification實際上所有這些機制都需要按預期工作。

0

我會去一個更簡單的實現。 NSNotificationCenter已經提供了您在應用中廣播和接收消息所需的所有機制。

如果您從後臺線程中發出通知,您可以使用GCD dispatch_async使其在主線程上交付。

對象類

dispatch_async(dispatch_get_main_queue(), ^{ 
    // You don't need to pass the object itself here as you are not using it later.  
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ScaleCountUpdated"]; 
} 

MainViewController

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Register your controller as an observer for a specific message name 
    [[NSNotificationCenter defaultCenter] addObserver: self 
              selector: @selector(updateScaleCount) 
               name: @"ScaleCountUpdated" 
               object: nil]; 

} 
- (void)updateScaleCount 
{ 
    NSLog(@"[ScalesViewController - updateScaleCount]: Scales updated from notification center."); 
    if([UserDefinedScales areScalesGrouped] == YES){ 
     self.groupCountLabel.text = [NSString stringWithFormat: @"Group Count: %i", [[UserDefinedScales sortedKeys] count]]; 
    } else { 
     self.groupCountLabel.text = @"Group Count: 1"; 
    } 
    self.scaleCountLabel.text = [NSString stringWithFormat: @"Scale Count: %i", [UserDefinedScales scaleCount]]; 
} 
相關問題