每个对象有多个代理?

Ser*_*nce 17 iphone cocoa-touch delegates objective-c ios

我有一个UIScrollView我需要子类,并在子类内我需要附加,UIScrollViewDelegate所以我可以实现该viewForZoomingInScrollView方法.

然后我有一个UIViewController我需要实例化UIScrollView我创建的这个子类的对象的地方,我还想UIScrollViewDelegate为这个对象创建一个UIViewController ,这样我就可以scrollViewDidZoom在这个UIViewController类中实现了.

怎么可能让一个对象有两个委托?(我知道我可以很容易地只有一个代表并且只在那里实现这两种方法,但出于设计目的,我想按照我提到的方式来实现).

zou*_*oul 15

有时将多个委托附加到滚动视图是有意义的.在这种情况下,您可以构建一个简单的委托拆分器:

// Public interface
@interface CCDelegateSplitter : NSObject

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

@end

// Private interface
@interface CCDelegateSplitter ()
@property(strong) NSMutableSet *delegates;
@end

@implementation CCDelegateSplitter

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

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

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

- (void) forwardInvocation: (NSInvocation*) invocation
{
    for (id delegate in _delegates) {
        [invocation invokeWithTarget:delegate];
    }
}

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

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

@end
Run Code Online (Sandbox Code Playgroud)

然后,只需将此拆分器的实例设置为滚动视图的委托,并将任意数量的委托附加到拆分器.所有人都将收到代表团的活动.一些警告适用,例如假设所有代表属于同一类型,否则您将无法respondsToSelector实现天真的实现.这不是一个大问题,很容易将实现更改为仅向支持它们的人发送委托事件.

  • 而不是[NSMutableSet set]; 使用[NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]; 因为它将保留对委托对象的弱引用,并将避免它们的保留周期 (2认同)

Tot*_*mus 7

您不希望具有2个委托的对象.您希望保持customScrollView对其自己的UIScrollViewDelegate函数负责.

要使您的parentVC响应UIScrollView的委托方法,您还必须在customScrollView中创建自定义委托.

在调用UIScrollViewDelegate函数时,您还将从自定义委托调用您的一个委托函数.这样,您的parentVC将在您想要的时刻响应.

看起来有点像这样.

CustomScrollView.h

@protocol CustomDelegate <NSObject>

//custom delegate methods
-(void)myCustomDelegateMethod;

@end

@interface CustomScrollView : UIScrollView <UIScrollViewDelegate>
{
    id<CustomDelegate> delegate
    //the rest of the stuff
Run Code Online (Sandbox Code Playgroud)

CustomScrollView.m

-(void) viewForZoomingInScrollView
{
    [self.delegate myCustomDelegateMethod];
    //rest of viewForZoomingInScrollView code
Run Code Online (Sandbox Code Playgroud)

ParentVC.h

@interface CustomScrollView : UIViewController <CustomDelegate>
{
    //stuff
Run Code Online (Sandbox Code Playgroud)

ParentVC.m

-(void)makeCustomScrollView
{
     CustomScrollView *csv = [[CustomScrollView alloc] init];
     csv.delegate = self;
     //other stuff

}

-(void)myCustomDelegateMethod
{
   //respond to viewForZoomingInScrollView
}
Run Code Online (Sandbox Code Playgroud)

我希望这完全涵盖你的问题.祝好运.

  • @TotumusMaximus一个ScrollView已经有一个名为"delegate"的属性,在这里你尝试声明一个具有相同名称的属性,这是一个BAD (2认同)