2013-07-27 76 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]]; 
} 
相关问题