Objective c 如何实现NSNotificationCenter(块样式)?

Objective c 如何实现NSNotificationCenter(块样式)?,objective-c,block,nsnotificationcenter,Objective C,Block,Nsnotificationcenter,这是一个面试问题。我知道如何使用NSDictionary实现非阻塞通知中心。但我不知道如何实现块通知中心,因为没有“观察者”。这是代码。有什么想法吗 #import <Foundation/Foundation.h> /** LBNotificationCenter.h */ typedef void (^Observer)(NSString *name, id data); @interface LBNotificationCenter : NSObject - (void

这是一个面试问题。我知道如何使用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 ()

@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
}
#导入
/**LBNotificationCenter.h*/
typedef void(^Observer)(NSString*名称,id数据);
@接口LBNotificationCenter:NSObject
-(void)addObserverForName:(NSString*)名称块:(Observer)块;
-(void)removeObserverForName:(NSString*)名称块:(Observer)块;
-(void)postNotification:(NSString*)名称数据:(id)数据;
@结束
/**LBNotificationCenter.m*/
@接口LBNotificationCenter()
@结束
@实施信息中心
-(instancetype)初始化
{
self=[super init];
如果(自我){
}
回归自我;
}
-(void)addObserverForName:(NSString*)名称块:(观察者)块
{
//在这里添加您的代码
}
-(void)removeObserverForName:(NSString*)名称块:(观察者)块
{
//在这里添加您的代码
}
-(void)postNotification:(NSString*)名称数据:(id)数据
{
//在这里添加您的代码
}

为什么不将块添加到
NSDictionary
?您可以像解释的那样进行操作

块是普通对象,因此可以将它们存储在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;
}
#导入
/**LBNotificationCenter.h*/
typedef void(^Observer)(NSString*名称,id数据);
@接口LBNotificationCenter:NSObject
-(void)addObserverForName:(NSString*)名称块:(Observer)块;
-(void)removeObserverForName:(NSString*)名称块:(Observer)块;
-(void)postNotification:(NSString*)名称数据:(id)数据;
@结束
/**LBNotificationCenter.m*/
@接口LBNotificationCenter()
@属性(强,非原子)NSMutableDictionary*观察者;
@结束
@实施信息中心
-(instancetype)初始化
{
self=[super init];
如果(自我){
_观察员=[NSMutableDictionary new];
}
回归自我;
}
-(void)addObserverForName:(NSString*)名称块:(观察者)块
{
//检查名称和块是否存在。。。
NSMutableArray*nameObservators=self.Observators[name];
如果(nameObservators==nil){
nameObservators=(self.obbservators[name]=[NSMutableArray new]);
}
[名称对象:块];
}
-(void)removeObserverForName:(NSString*)名称块:(观察者)块
{
//检查名称和块是否存在。。。
NSMutableArray*nameObservators=self.Observators[name];
//有些人可能会争辩说,不需要这种检查
//as Objective-C允许无消息传递
//我宁愿把它说清楚
如果(nameObservators==nil){
返回;
}
[名称移除对象:块];
}
-(void)postNotification:(NSString*)名称数据:(id)数据
{
//检查名称和数据是否存在。。。
NSMutableArray*nameObservators=self.Observators[name];
如果(nameObservators==nil){
返回;
}
for(观察员名称中的观察员){
观察员(姓名、数据);
}
}
@结束
int main(int argc,const char*argv[]{
@自动释放池{
NSString*const Notification1=@“Notification1”;
NSString*const Notification2=@“Notification2”;
LBNotificationCenter*notificationCenter=[LBNotificationCenter新建];
观察者observer1=^(NSString*名称,id数据){
NSLog(@“observer 1是为名称:%@调用的,其中有些数据:%@”,名称,数据);
};
观察者observer2=^(NSString*名称,id数据){
NSLog(@“observer 2是为名称:%@调用的,其中有些数据:%@”,名称,数据);
};
[notificationCenter addObserverForName:Notification1块:observer1];
[notificationCenter addObserverForName:Notification2块:observer2];
[notificationCenter postNotification:Notification1数据:@“某些数据”];
[notificationCenter postNotification:Notification2数据:@“某些数据”];
[notificationCenter removeObserverForName:Notification1块:observer1];
//此时没有观察者正在侦听,因此没有通知1的日志。。。
[notificationCenter postNotification:Notification1数据:@“某些数据”];
[notificationCenter postNotification:Notification2数据:@“某些数据”];
}
返回0;
}

酷!我理解!谢谢你的帮助!您好,Stanislav,请问如何设置观察者名称并让观察者对象在main()中调用removeForName?谢谢,我已经更新了我的答案。让我知道它是否适合你。像一个魔咒一样工作!非常感谢。是的,你是对的。我对block和notification center都不熟悉。谢谢你的回答。