2012-03-23 52 views
4

我正在尝试使用通知。在我的视图控制器类中,我有一个bool isFullScreen。当这个布尔的值发生变化时,我想要发送一个通知给所有观察类。我不太清楚如何去做这件事,因为BOOL不是一个对象。我怎么做到这一点?如何发布到NSNotificationCenter关于布尔状态?

回答

10
[[NSNotificationCenter defaultCenter] postNotificationName:YourNotificationName object:[NSNumber numberWithBool:isFullScreen]]; //YourNotificationName is a string constant 

志愿例子:

如果你有志愿做它,它会像下面....:

[self addObserver:self forKeyPath:@"isFullScreen" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil]; 

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
if ([keyPath isEqualToString: @"isFullScreen"]) { 
     BOOL newValue = [[change objectForKey:NSKeyValueChangeNewKey] boolValue]; 
    } 
} 

//and in dealloc 
[self removeObserver:self forKeyPath:@"isFullScreen" ]; 
+0

所以任何时候都是全屏显示值的变化,th通知被发送了吗? – Snowman 2012-03-23 14:20:08

+0

不,您必须发送它... – bandejapaisa 2012-03-23 14:21:06

+0

您可能更喜欢在isFullScreen变量上添加KVO。阅读这个。您注册为isFullScreen的KVO观察员,并且每次更改时,您都会收到通知 – bandejapaisa 2012-03-23 14:21:52

3

只是wrap BOOL中的NSNumber:

[NSNumber numberWithBool:myBool] 
2

你可以在提到的bandejapaisa和beryllium中包装NSNumber中的BOOL。但是,为了通知观察者对简单属性的更改,最好使用Key Value Observing(KVO),而不是NSNotificationCenter。只要您已经实施了或符合KVC标准的访问方法,就可以免费获得KVO。就像这样:

// In your .h: 

@interface YourViewController : UIViewController 

@property (getter = isFullScreen) BOOL fullScreen; 

@end 

// In your .m: 

@implementation YourViewController 

@synthesize fullScreen; 

@end 

// In your observer class(es): 

// Start observing the viewController for changes to fullScreen (in awakeFromNib, or wherever it makes sense) 
[self.viewController addObserver:self forKeyPath:@"fullScreen" options:0 context:NULL]; 

// This method is called when an observed value changes 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if (object == viewController && [keyPath isEqualToString:@"fullScreen"]) 
    { 
     if (self.viewController.isFullScreen) 
     { 
      // Do whatever you need to do in response to isFullScreen being true 
     } 
     else 
     { 
      // Do whatever you need to do in response to isFullScreen being false 
     } 
    } 
} 

为了这个工作,你需要确保你实际上调用setScreen属性的setter。因此,请始终使用来代替fullScreen = YES。否则,setter方法不会被调用,并且KVO不会被触发。您应该阅读documentation on KVO。了解它是成为一名优秀的iOS程序员的基本要素。

+0

所以我有两个类,FirstClass和SecondClass。 FirstClass具有属性isFullScreen。如果我希望SecondClass知道对FirstClass.isFullScreen的任何更改,这将如何看待? – Snowman 2012-03-23 14:36:15

+0

SecondClass必须通过Interface Builder连接或通过以编程方式设置的关系来了解FirstClass的实例。 SecondClass将自己注册为FirstClass实例的fullScreen属性更改的观察者,然后将通知属性更改。 – 2012-03-23 14:48:57

0

您可以使用NSMutableString *作为@“YES”和@“NO”来解决这个问题。然后,当你设置字符串@“YES”,一切都在志愿观测会被通知:

[myStringProperty setString:@"YES"]; 

必须使用的NSString了setString value.That是实际调用它。

警告不要使用:

myStringProperty = @"YES"; 

(这不会产生志愿通知。)

0

通知的object应张贴通知,而不是一个NSNumber对象。这很重要,以便观察者可以观察特定的实例,并且对调用者来说显而易见的是所有值。通过object传递数据是获取“不响应选择器”崩溃的简单方法。更改数据通常在userInfo字典中,但简单的BOOL通常用两个通知来处理。在这种情况下,您应该有:

MYViewControlDidEnterFullScreenNotification 
MYViewControlDidExitFullScreenNotification 

object应该是相关的视图控制器。

请注意,这些通知在时间上非常明确。 之后都发生了变化。您也可以有相应的Will通知。请查看notification listNSWindow,以了解如何正确执行此操作的一个很好的示例。请特别注意NSWindowDidEnterFullScreenNotification及其亲属。

您可能也有兴趣Some thoughts on NSNotifications

关于KVO的评论很好,通常KVO是一个体面的方法来实现这一点。但通知也很好,比KVO更容易理解和调试。

0

通知的对象字段用来传递发送者和不附加PARMS

正确的方法是使用USERINFO发送一个密钥值字典

例如

- (void)postNotificationFullScreen //post notification method and logic 
{ 
    NSString *notificationName = @"applicationFullScreen"; 
    NSString *key = @"fullScreen"; 
    NSDictionary *dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:self.fullScreen] forKey:key]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:nil userInfo:dictionary]; 
} 

而且要读取这个

NSString *notificationName = @"applicationFullScreen"; 

[[NSNotificationCenter defaultCenter] 
    addObserver:self 
    selector:@selector(useFullScreen:) 
    name:notificationName 
    object:nil]; 

- (void)useFullScreen:(NSNotification *)notification //use notification method and logic 
{ 
    NSString *key = @"fullScreen"; 
    NSDictionary *dictionary = [notification userInfo]; 
    BOOL boolValue; 
    if([dictionary valueForKey:key]) 
     boolValue =[[dictionary valueForKey:key] boolValue]; 
}