由于委托是一个简单的变量,分配给它会覆盖值而不是添加它。您可以将其转换为数组,但由于 NSArray 保持对其中对象的强引用,您需要处理潜在的循环引用。(在这种情况下,循环引用是两个对象相互拥有。由于它们都由某人拥有,因此两者都不会被释放。即使它们只拥有彼此。维基百科有更多。但 Objective-C 中的典型模式是出于这个原因,使所有代表变得虚弱。)
您可能希望考虑使用NSNotificationCenter
通知,而不是委托。
它们不是 1:1,而是 1:any(包括 0 没有特殊考虑)。这个想法是一个对象发布一个通知,对它感兴趣的对象会观察它。每个对象都可以选择他们感兴趣的事件。
您需要执行几个步骤:
- 删除您编写的所有委托代码。
- 同意通知名称。
- 注册将响应通知的对象。(这是您设置委托的地方。)
- 处理通知。
- 发布通知(您之前调用代理的位置)。
- 对象被销毁时取消注册。
你要做的就是在一个键上达成一致,可能是一个常数。
键.h:
extern NSString *MethodOneNotification;
键.m:
NSString *MethodOneNotification = @"MethodOneNotification";
然后注册firstViewController
并secondViewController
喜欢这样的地方viewDidLoad
:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(methodOneNotification:) object:nil];
firstViewController
为选择器提供一个处理程序secondViewController
:
- (void)methodOneNotification:(NSNotification *)notification {
NSLog(@"%@ got the notification!", [self class]);
}
在您之前调用代理的位置调用通知:
[[NSNotificationCenter defaultCenter] postNotificationName:MethodOneNotification
object:nil];
在firstViewController
and中secondViewController
,您需要删除通知注册(当然是在 dealloc 中):
- (void)dealloc {
[[NSNotification defaultCenter] removeObserver:self name:MethodOneNotification
object:nil];
// [super dealloc] if you're not using ARC, but you should be
}
在通知处理程序中,您可以将通知的发送者作为notification.object
. 如果您需要与通知一起传递信息,您可以使用postNotification:
接受 a的不同变体NSDictionary
,然后您可以访问字典作为notification.userInfo
.
如果您需要将值返回给发布消息的对象,则必须通过向发布者发送消息(您可以访问 as notification.object
)将它们发回。例如:
- (void)methodOneNotification:(NSNotification *)notification {
AppDelegate *appDelegate = notification.object;
[appDelegate returningValue:1];
}
在这里,显然 AppDelegate 需要定义和处理-(void)returningValue:(int)value
.
您需要保留类实例的返回值。当然,如果您可能有多个返回,则需要将它们收集到returningValue:
一个数组中。但至少你已经跳过了循环引用。
解决这个问题的另一种方法是使用块。不过,这会使这个答案的大小增加一倍。:) 底线,虽然:委托模式是这个问题的错误模式。幸运的是,其他人很容易上手。