Как опубликовать в NSNotificationCenter о состоянии bool? - PullRequest
5 голосов
/ 23 марта 2012

Я пытаюсь освоить использование уведомлений. В моем классе контроллера представления у меня есть bool isFullScreen. Когда значение этого параметра изменяется, я хочу, чтобы уведомление было отправлено всем наблюдающим классам. Я не совсем уверен, как это сделать, поскольку BOOL не является объектом. Как мне это сделать?

Ответы [ 6 ]

10 голосов
/ 23 марта 2012
[[NSNotificationCenter defaultCenter] postNotificationName:YourNotificationName object:[NSNumber numberWithBool:isFullScreen]]; //YourNotificationName is a string constant

КВО Пример:

Если бы вы делали это с 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" ];
4 голосов
/ 23 марта 2012

Just wrap BOOL в NSNumber:

[NSNumber numberWithBool:myBool]
2 голосов
/ 23 марта 2012

Вы можете обернуть BOOL в NSNumber, как упомянуто bandejapaisa и бериллий.Тем не менее, для уведомления наблюдателей об изменениях в простом свойстве лучше использовать Key Value Observing (KVO) вместо NSNotificationCenter.Вы получаете KVO «бесплатно», если вы внедрили или @synthesized методы доступа, совместимые с KVC.Примерно так:

// 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.Поэтому всегда делайте self.fullScreen = YES из [self setFullScreen:YES] вместо fullScreen = YES.В противном случае метод установки не вызывается, и KVO не запускается.

Вам следует прочитать документацию по KVO .Понимание этого очень важно для хорошего программиста iOS.

0 голосов
/ 26 августа 2014

Поле объекта уведомления предназначено для передачи отправителю, а не для дополнительных параметров

Правильный способ - использовать 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];
}
0 голосов
/ 23 марта 2012

object уведомления должен быть объектом, отправляющим уведомление, а не NSNumber.Это важно для того, чтобы наблюдатель мог наблюдать конкретные случаи, и чтобы для вызывающего абонента было очевидно, что все значения.Передача данных в object - это простой способ получить «не отвечает на селектор» сбои.Данные об изменениях обычно идут в формате userInfo, но простые BOOL обычно обрабатываются двумя уведомлениями.В этом случае вы должны иметь:

MYViewControlDidEnterFullScreenNotification
MYViewControlDidExitFullScreenNotification

object должен быть соответствующим контроллером представления.

Обратите внимание, что эти уведомления очень четкие по времени.Оба случаются после состояние изменилось.Вы также можете иметь эквивалентные Will уведомления.Посмотрите на список уведомлений для NSWindow для хорошего примера того, как сделать это правильно.Обратите особое внимание на NSWindowDidEnterFullScreenNotification и его родственников.

Вы также можете быть заинтересованы в Некоторые мысли о NSNotifications .

Комментарии к KVO хорошие, и часто KVOдостойный способ добиться этого.Но уведомления тоже хороши, и их легче понять и отладить, чем KVO.

0 голосов
/ 23 марта 2012

Вы можете решить эту проблему, используя NSMutableString * как @ "YES" и @ "NO".Затем, когда вы установите строку в @ "YES", и все, что наблюдает в KVO, будут уведомлены:

[myStringProperty setString:@"YES"];

Вы должны использовать значение setString NSString. Это то, что фактически вызывает его.

ПРЕДУПРЕЖДЕНИЕ НЕ используйте:

myStringProperty = @"YES";

(Это не приведет к уведомлениям KVO.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...