NSNotification сохраняет объект? - PullRequest
21 голосов
/ 18 марта 2011

Мой вопрос касается объекта, который добавляется в метод -postNotificationName:object: userInfo:.

Сохраняет ли NSNotification объект? (аналогично NSMutableDictionary или Array) ... то есть я могу освободить объект после публикации уведомления

* 1007фрагмент кода, чтобы помочь описать мой вопрос ... действительно ли выпустить объект.Ссылка на документацию Apple может быть очень полезна.
NSMutableDictionary *teamDictCopy = [self.teamDict mutableCopy];
[teamDictCopy setObject:[NSNumber numberWithInt:self.scrollViewIndex] forKey:@"imageIndex"];

if([self.statusButton.title isEqualToString:@"Completed"]){
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UnComplete" object:teamDictCopy userInfo:nil];
}

[teamDictCopy release];

Ответы [ 2 ]

31 голосов
/ 18 марта 2011

"Сохраняет ли NSNotification объект? (Аналогично NSMutableDictionary или Array) ... то есть я могу освободить объект после отправки уведомления"

Яне уверен, что параметры object и userInfo сохраняются этим методом или нет, но на практике это не должно иметь большого значения.

Я думаю, вы, возможно, предполагаете, что NSNotificationCenter создает этиуведомления и их трансляция в асинхронном режиме, но это не так.Как указано в документации для NSNotificationCenter (см. Ссылка на класс NSNotificationCenter ), уведомления отправляются синхронно:

Центр уведомлений доставляет уведомления наблюдателям синхронно.Другими словами, методы postNotification: не возвращаются, пока все наблюдатели не получили и не обработали уведомление.Для асинхронной отправки уведомлений используйте NSNotificationQueue.В многопоточном приложении уведомления всегда доставляются в потоке, в котором было опубликовано уведомление, что может не совпадать с тем, в котором зарегистрирован сам наблюдатель.

Итак, в вашем коде уведомлениеЦентр создает уведомление, а затем передает его через центр по умолчанию.Любые объекты, которые зарегистрировались для этой комбинации имени уведомления и объекта, получат уведомление и затем выполнят селектор, который они указали, когда они зарегистрировались для этого уведомления.После этого элемент управления возвращается в класс, который разместил уведомление.

Другими словами, к тому времени, когда ваш код попадет в строку [teamDictCopy release], teamDictCopy уже будет «использоваться» всемизаинтересованные стороны.Таким образом, не должно быть никакой опасности в его выпуске.

Просто примечание о соглашениях.Как правило, параметр object: предназначен для объекта, отправляющего уведомление, а параметр userInfo: предназначен для NSDictionary дополнительной информации.Поэтому обычно вы обрабатываете уведомление следующим образом:

NSMutableDictionary *teamDictCopy = [self.teamDict mutableCopy];
[teamDictCopy setObject:
   [NSNumber numberWithInt:self.scrollViewIndex] forKey:@"imageIndex"];

if([self.statusButton.title isEqualToString:@"Completed"]){
 [[NSNotificationCenter defaultCenter] postNotificationName:@"UnComplete" 
     object:self userInfo:teamDictCopy];
    }

[teamDictCopy release];
5 голосов
/ 18 марта 2011

да - вы можете освободить объект, как только он будет установлен в качестве объекта уведомления.

вы также можете подкласс.один, в частности.

это, однако, основа объектов, их переменных экземпляра и распределенной связи и сигнализации, когда типы идентифицируются как объекты.

я написал тест для вас, так что вы можете быть уверены в этом.случаев использования уведомлений было бы немного, если бы объект не был сохранен.просто добавьте точку останова, где указано, затем запустите с включенными точками останова.наслаждайтесь!

#import <Foundation/Foundation.h>

@interface MONObject : NSObject
@end

@implementation MONObject

- (id)retain {
    return self; /* << add breakpoint here */
}

/* needed to counter retain override
   (although all MONObjects will leak in this example)
*/
- (void)release {
}

@end

int main(int argc, const char* argv[]) {
    NSAutoreleasePool * pool = [NSAutoreleasePool new];

    NSString * name = @"UnComplete";
    MONObject * obj = [MONObject new];
    [[NSNotificationCenter defaultCenter] postNotificationName:name object:obj userInfo:nil];
    [obj release], obj = 0;

    [pool drain];
    return 0;
}
...