如何发布关于bool状态的NSNotificationCenter?

时间:2012-03-23 14:15:25

标签: iphone objective-c ios

我正在尝试使用通知。在我的视图控制器类中,我有一个bool isFullScreen。当这个bool的值发生变化时,我希望将通知发送给所有观察类。我不太确定如何做到这一点,因为BOOL不是一个对象。我该如何做到这一点?

6 个答案:

答案 0 :(得分:10)

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

KVO示例:

如果你是用KVO做的话,那就像下面这样....:

[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" ];

答案 1 :(得分:4)

NSNumber中只有wrap BOOL:

[NSNumber numberWithBool:myBool]

答案 2 :(得分:2)

你可以将一个BOOL包装在NSNumber中,例如bandejapaisa和beryllium。但是,为了通知观察者对简单属性的更改,最好使用Key Value Observing(KVO)而不是NSNotificationCenter。只要您实现了@synthesized 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
        }
    } 
}

为此,您需要确保实际调用fullScreen属性的setter。因此,始终self.fullScreen = YES而不是[self setFullScreen:YES]而不是fullScreen = YES。否则,不会调用setter方法,也不会触发KVO。

您应该阅读documentation on KVO。理解它是成为一名优秀的iOS程序员的基础。

答案 3 :(得分:0)

您可以使用NSMutableString *作为@“YES”和@“NO”来解决这个问题。然后,当您将字符串设置为@“YES”时,将通知KVO中观察到的所有内容:

[myStringProperty setString:@"YES"];

您必须使用NSString setString值。这就是实际调用它的内容。

警告请勿使用:

myStringProperty = @"YES";

(这不会产生KVO通知。)

答案 4 :(得分:0)

通知的object应该是发布通知的对象,而不是NSNumber。这很重要,以便观察者可以观察特定的实例,因此调用者可以明白这些值是什么。在object中传递数据是获取“不响应选择器”崩溃的简单方法。更改数据通常在userInfo dict中,但是简单的BOOL通常用两个通知处理。在这种情况下,您将拥有:

MYViewControlDidEnterFullScreenNotification
MYViewControlDidExitFullScreenNotification

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

请注意,这些通知的时间非常明确。在状态发生变化之后,两者都发生了。您还可以拥有等效的Will通知。查看NSWindow的{​​{3}},了解如何正确执行此操作的一个很好的示例。请特别注意NSWindowDidEnterFullScreenNotification及其亲属。

您可能也对notification list感兴趣。

对KVO的评论很好,通常KVO是实现这一目标的一种不错的方式。但是通知也很好,比KVO更容易理解和调试。

答案 5 :(得分:0)

通知的对象字段是用于传递发件人而不是其他参数

正确的方法是使用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];
}