这是一个面试问题。我知道如何使用NSDictionary实现非阻止通知中心。但是我不知道如何实现阻止NSNotification中心,因为没有"观察者"。这是代码。有什么想法吗?
#import <Foundation/Foundation.h>
/** LBNotificationCenter.h */
typedef void (^Observer)(NSString *name, id data);
@interface LBNotificationCenter : NSObject
- (void)addObserverForName:(NSString *)name block:(Observer)block;
- (void)removeObserverForName:(NSString *)name block:(Observer)block;
- (void)postNotification:(NSString *)name data:(id)data;
@end
/** LBNotificationCenter.m */
@interface LBNotificationCenter ()
@end
@implementation LBNotificationCenter
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
- (void)addObserverForName:(NSString *)name block:(Observer)block
{
//add your code here
}
- (void)removeObserverForName:(NSString *)name block:(Observer)block
{
//add your code here
}
- (void)postNotification:(NSString *)name data:(id)data
{
//add your code here
}
答案 0 :(得分:3)
块是普通对象,因此您可以将它们存储在NSArray / NSDictionary中。说实现很简单。
#import <Foundation/Foundation.h>
/** LBNotificationCenter.h */
typedef void (^Observer)(NSString *name, id data);
@interface LBNotificationCenter : NSObject
- (void)addObserverForName:(NSString *)name block:(Observer)block;
- (void)removeObserverForName:(NSString *)name block:(Observer)block;
- (void)postNotification:(NSString *)name data:(id)data;
@end
/** LBNotificationCenter.m */
@interface LBNotificationCenter ()
@property (strong, nonatomic) NSMutableDictionary <id, NSMutableArray <Observer> *> *observers;
@end
@implementation LBNotificationCenter
- (instancetype)init
{
self = [super init];
if (self) {
_observers = [NSMutableDictionary new];
}
return self;
}
- (void)addObserverForName:(NSString *)name block:(Observer)block
{
// check name and block for presence...
NSMutableArray *nameObservers = self.observers[name];
if (nameObservers == nil) {
nameObservers = (self.observers[name] = [NSMutableArray new]);
}
[nameObservers addObject:block];
}
- (void)removeObserverForName:(NSString *)name block:(Observer)block
{
// check name and block for presence...
NSMutableArray *nameObservers = self.observers[name];
// Some people might argue that this check is not needed
// as Objective-C allows messaging nil
// I prefer to keep it explicit
if (nameObservers == nil) {
return;
}
[nameObservers removeObject:block];
}
- (void)postNotification:(NSString *)name data:(id)data
{
// check name and data for presence...
NSMutableArray *nameObservers = self.observers[name];
if (nameObservers == nil) {
return;
}
for (Observer observer in nameObservers) {
observer(name, data);
}
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *const Notification1 = @"Notification1";
NSString *const Notification2 = @"Notification2";
LBNotificationCenter *notificationCenter = [LBNotificationCenter new];
Observer observer1 = ^(NSString *name, id data) {
NSLog(@"Observer1 is called for name: %@ with some data: %@", name, data);
};
Observer observer2 = ^(NSString *name, id data) {
NSLog(@"Observer2 is called for name: %@ with some data: %@", name, data);
};
[notificationCenter addObserverForName:Notification1 block:observer1];
[notificationCenter addObserverForName:Notification2 block:observer2];
[notificationCenter postNotification:Notification1 data:@"Some data"];
[notificationCenter postNotification:Notification2 data:@"Some data"];
[notificationCenter removeObserverForName:Notification1 block:observer1];
// no observer is listening at this point so no logs for Notification1...
[notificationCenter postNotification:Notification1 data:@"Some data"];
[notificationCenter postNotification:Notification2 data:@"Some data"];
}
return 0;
}
答案 1 :(得分:0)
为什么不将这些块添加到NSDictionary
?你可以像解释in this answer