Objective c 单例对象的委托
我有一个NSObject,它是一个singleton。这个单例类是否存在委托问题?我担心对于单例类型来说它会失败Objective c 单例对象的委托,objective-c,ios,cocoa-touch,Objective C,Ios,Cocoa Touch,我有一个NSObject,它是一个singleton。这个单例类是否存在委托问题?我担心对于单例类型来说它会失败 这是我的设想。我有一个函数(在这个单例类中),它执行异步请求,从API中提取NSDictionary。基本上,当这个请求完成时,我想通知一个类请求已经完成最健壮的顺序排列) 保持简单 将你的应用程序设计为永远不要让多个对象同时成为singleton的代理(这可能是不可能的) NSNotification 使用NSNotificationCenter发出事件信号,而不是委派。请参阅此帖
这是我的设想。我有一个函数(在这个单例类中),它执行异步请求,从API中提取NSDictionary。基本上,当这个请求完成时,我想通知一个类请求已经完成不,代表不会失败,而是考虑使用:
您基本上有三种选择:
- 使用委托。singelton是一个对象,因此它当然可以有一个委托。如果有多个对象需要使用它,并且需要将自己设置为代理,则每次都可以重置它们,但这可能会有问题
- 使用通知,如Richard J.Ross III所示,但严肃地说:我觉得很奇怪,如果你是单身,需要通知一位代表,但你会使用广播技术
- 使用完成块,其中调用对象将一个块传递给singleton,一旦singleton完成任务,该块就会被执行。请参阅(好的,这不是一个单例,而是一个类方法。原理相同),它使用一个完成块,或者使用一个成功块和一个失败块的great。
根据其示例代码:[[AFGowallaAPIClient sharedClient] getPath:urlString parameters:mutableParameters success:^(__unused AFHTTPRequestOperation *operation, id JSON) { NSMutableArray *mutableRecords = [NSMutableArray array]; for (NSDictionary *attributes in [JSON valueForKeyPath:@"spots"]) { Spot *spot = [[[Spot alloc] initWithAttributes:attributes] autorelease]; [mutableRecords addObject:spot]; } if (block) { block([NSArray arrayWithArray:mutableRecords]); } } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { if (block) { block([NSArray array]); } }];
- 如果对象A调用setDelegate:,紧接着对象B调用setDelegate:,则对象A将永远不会收到委托调用
- 在取消设置singleton的委托之前,需要检查您是否是委托人。通常在
中调用dealloc
singleton.delegate=nil代码>。若另一个对象恰好在您之后成为委托,那个么您只是让它们意外地停止成为委托
setDelegate:
替换为:addDelegate:
和removeDelegate:
@property (atomic) NSMutableArray *delegates;
- (void)addDelegate:(NSObject * <YourProtocol>)foo {
[self.delegates addObject:foo];
}
- (void)removeDelegate:(NSObject * <YourProtocol>)foo {
[self.delegates removeObject:foo];
}
- (void)signalDelegateEvent {
[self.delegates enumerateObjectsUsingBlock:^(id<YourProtocol> obj,
NSUInteger idx,
BOOL *stop) {
// call delegate method `foo` on each delegate
if ( [obj respondsToSelector:@selector(foo)]) {
[obj foo];
}
}];
}
@property(原子)NSMutableArray*委托;
-(void)addDelegate:(NSObject*)foo{
[self.addObject:foo];
}
-(void)removeDelegate:(NSObject*)foo{
[self.delegates-removeObject:foo];
}
-(无效)signalDelegateEvent{
[self.delegates枚举对象使用块:^(id对象,
整数idx,
BOOL*停止){
//对每个委托调用委托方法'foo'
if([obj respondsToSelector:@selector(foo)]){
[obj foo];
}
}];
}
我已经在许多应用程序中成功地使用了多代理模式。如果选择这种方法,请仔细考虑多线程是如何影响事情的。为什么代理会失败?对于多个侦听器,您可以考虑使用<代码> NSNotificationCenter < /代码>。我只有一个类要通知,也更新了问题上下文。above@adit如果您迫切需要加快观察者查找速度,您可以在单例中使用一个特殊的
NSNotificationCenter
。在这种情况下,只需将其设置为singleton的只读属性,以便观测者可以直接向其注册。这确实是一种糟糕的形式。为什么有人会故意这样修改代码?请参阅vikingosegundo的答案,了解两个更好的解决方案,其中包括一名代表或blocks@PostCodeism我不太明白。我的代码有什么问题?您将如何使用NSNotificationCenter?@RichardJ.RossIII抱歉,这是一种过度反应。具体来说,您的代码没有问题,我更喜欢谈论NSNotifications。只是NSNotifications被过度使用是因为它们很简单,但它们很难通过代码进行跟踪。总的来说,对于iOS中的单例,块将是更好的解决方案。@PostCodeism no,而不是多播解决方案。它们都是用于不同场景的工具,显然没有通用的解决方案。我从未想过使用多代理解决方案,谢谢你的想法。很高兴在头脑中有一个委托模式的变体。如何使用一个必需的回调来通知委托对象它们即将被替换?此解决方案可以使用NSSet而不是NSArray来收集委托,以确保没有任何内容接收到多条消息。亲爱的审阅者:编辑一篇文章来修复打字错误是可以的,非常感谢。但添加到我甚至不知道的库的链接不是。
@property (atomic) NSMutableArray *delegates;
- (void)addDelegate:(NSObject * <YourProtocol>)foo {
[self.delegates addObject:foo];
}
- (void)removeDelegate:(NSObject * <YourProtocol>)foo {
[self.delegates removeObject:foo];
}
- (void)signalDelegateEvent {
[self.delegates enumerateObjectsUsingBlock:^(id<YourProtocol> obj,
NSUInteger idx,
BOOL *stop) {
// call delegate method `foo` on each delegate
if ( [obj respondsToSelector:@selector(foo)]) {
[obj foo];
}
}];
}