委派给多个对象

S.J*_*S.J 28 objective-c

有没有办法在Objective-C中一次委托两个对象?我知道委托模式一次意味着一个响应,并且对于多个听众和广播有通知中心但通知不会返回任何值.

如果我有一个基于网络的大量iOS项目并且需要委托给多个侦听器并且需要从它们返回值,那么在这种情况下哪种方法应该是最好的?

Ram*_*uri 32

在每个班级中,代表都是一名,因此一名代表被告知该事件.但没有什么禁止你用一组委托声明一个类.

或者使用观察.可以通过多个类来观察类.

根据OP的要求,因为一些代码也很有用,这是一种方法:

@interface YourClass()

@property (nonatomic, strong, readwrite) NSPointerArray* delegates;
// The user of the class shouldn't even know about this array
// It has to be initialized with the NSPointerFunctionsWeakMemory option so it doesn't retain objects

@end  

@implementation YourClass

@synthesize delegates;

...   // other methods, make sure to initialize the delegates set with alloc-initWithOptions:NSPointerFunctionsWeakMemory

- (void) addDelegate: (id<YourDelegateProtocol>) delegate
{
    [delegates addPointer: delegate];
}

- (void) removeDelegate: (id<YourDelegateProtocol>) delegate
{
    // Remove the pointer from the array
    for(int i=0; i<delegates.count; i++) {
        if(delegate == [delegates pointerAtIndex: i]) {
            [delegates removePointerAtIndex: i];
            break;
        }
    } // You may want to modify this code to throw an exception if no object is found inside the delegates array
}

@end
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的版本,你可以用另一种方式完成.我不建议公开委托设置,你永远不知道如何使用它,你可以得到一个不一致的状态,特别是多线程.此外,当您添加/删除委托时,您可能需要运行其他代码,这就是为什么将委托设置为私有的原因.
您可能还有许多其他方法delegatesCount,例如.

PS:代码已被编辑为NSPointerArray而不是NSMutableSet,因为如注释中所述,委托应该使用弱指针来避免保留周期.

  • 并且不要忘记在你的deallocs中调用removeDelegate. (2认同)
  • 这个答案很容易出错.你必须在dealloc函数之前调用"removeDelegate".由于此可变集将增加保留计数,因此您将对委托对象具有强引用.因此,代理的'dealloc'功能永远不会被调用.因此,您必须在其他地方手动释放它.小心,这个答案肯定会以这种方式导致隐藏的内存泄漏.使用此实现,而不是使用简单的普通指针:https://github.com/sergeyzenchenko/MulticastDelegate/blob/master/GCDMulticastDelegate.h (2认同)

小智 20

除了Ramys的答案,你可以使用a [NSHashTable weakObjectsHashTable]而不是a NSMutableSet.这将只保留对您的委托的弱引用,并防止您遇到内存泄漏.您将从标准的弱代理中获得您已经知道的相同行为@property (nonatomic, weak) id delegate;

@interface YourClass()

@property (nonatomic, strong) NSHashTable *delegates;

@end  

@implementation YourClass

- (instancetype)init
{
    self = [super init];
    if (self) {
        _delegates = [NSHashTable weakObjectsHashTable];
    }
    return self;
}

- (void) addDelegate: (id<YourDelegateProtocol>) delegate
{
    // Additional code
    [_delegates addObject: delegate];
}

// calling this method is optional, because the hash table will automatically remove the delegate when it gets released
- (void) removeDelegate: (id<YourDelegateProtocol>) delegate
{
    // Additional code
    [_delegates removeObject: delegate];
}

@end
Run Code Online (Sandbox Code Playgroud)