0

1 つのオブジェクトごとに複数のデリゲートという質問について 答えの1つは、興味深い解決策を思いつきました(少なくとも私の素朴な目にとって):オブジェクト(この場合はUIScrollView)が複数のデリゲート(この場合はUIScrollViewDelegate)を持つことを可能にする「デリゲートスプリッタ」を作成します。

コードは次のとおりです。

@interface DelegateSplitter : NSObject

-(void)addDelegate:(id)delegate;
-(void)addDelegates:(NSArray*)array;

@end


@interface DelegateSplitter()

@property NSMutableSet *delegates;

@end

@implementation DelegateSplitter

-(id)init
{
   self = [super init];
   _delegates = [NSMutableSet set];
   return self;
}

-(void)addDelegate:(id)delegate
{
  [_delegates addObject:delegate];
}

-(void)addDelegates:(NSArray *)array
{
   [_delegates addObjectsFromArray:array];
}

-(void)forwardInvocation:(NSInvocation *)anInvocation
{
  for (id delegate in _delegates)
  {
     if([delegate respondsToSelector:anInvocation.selector])
     {
        [anInvocation invokeWithTarget:delegate];
     }
   }
}

- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector
{
  NSMethodSignature *our = [super methodSignatureForSelector:selector];
  NSMethodSignature *delegated = [[_delegates anyObject]
                                  methodSignatureForSelector:selector];
  return our ? our : delegated;
}

- (BOOL) respondsToSelector: (SEL) selector
{
   return [[_delegates anyObject] respondsToSelector:selector];
}

このコードの問題は、保持サイクルが作成され、通常のデリゲートとは異なり、次のように宣言できないことです。

@property (assign) DelegateSplitter *splitter;

ただし、ラッパーよりも「優れた」ソリューションのようです。とにかく、保持サイクルを回避する方法はありますか?

4

1 に答える 1