Objective c 如何实现NSNotificationCenter(块样式)?
这是一个面试问题。我知道如何使用NSDictionary实现非阻塞通知中心。但我不知道如何实现块通知中心,因为没有“观察者”。这是代码。有什么想法吗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
#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都不熟悉。谢谢你的回答。