每个对象有多个代表?

我有一个UIScrollView ,我需要子类和子类内我需要附加UIScrollViewDelegate所以我可以实现viewForZoomingInScrollView方法。

然后我有一个UIViewController ,我需要实例化我创build的这个UIScrollView子类的一个对象,我也想使UIViewController成为这个对象的UIScrollViewDelegate ,所以我可以在这个UIViewController类中实现scrollViewDidZoom

如何使一个对象有两个代表? (我知道我可以很容易地只有一个委托,只是在那里实现这两个方法,但为了devise的目的,我想按照我提到的方式来做)。

你不想要一个2代表的对象。 你想保持你的customScrollView保持自己的UIScrollViewDelegate函数的责任。

为了让你的父VC对UIScrollView的委托方法作出响应,你必须在你的customScrollView里面做一个自定义委托。

在调用UIScrollViewDelegate函数的同时,您还将调用您的自定义委托中的一个委托函数。 这样你的父VC会在你想要的时候做出响应。

它看起来有点像这样。

CustomScrollView.h

 @protocol CustomDelegate <NSObject> //custom delegate methods -(void)myCustomDelegateMethod; @end @interface CustomScrollView : UIScrollView <UIScrollViewDelegate> { id<CustomDelegate> delegate //the rest of the stuff 

CustomScrollView.m

 -(void) viewForZoomingInScrollView { [self.delegate myCustomDelegateMethod]; //rest of viewForZoomingInScrollView code 

ParentVC.h

 @interface CustomScrollView : UIViewController <CustomDelegate> { //stuff 

ParentVC.m

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

我希望这完全覆盖你的问题。 祝你好运。

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

 // 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 

然后,简单地将此分离器的实例设置为滚动视图的委托,并将任意数目的代表附加到分离器。 他们都会收到代表团的活动。 有些注意事项是适用的,例如所有代表被假定为相同的types,否则你将遇到天真的respondsToSelector实现的麻烦。 这不是一个大问题,很容易将实现更改为仅向支持它们的用户发送委派事件。

简短的回答:你不。 代表通常是弱一对一的关系:

 @property (nonatomic, weak /*or assign*/) id<MyViewDelegate> delegate; 

有时你会看到一个“倾听者”的devise模式,这是代表的一对多forms:

 - (void) addListener:(id<MyViewListener>)listener; - (void) removeListener:(id<MyViewListener>)listener; 

在你的情况下,UIScrollView中似乎没有一个好的公共覆盖点,允许子类指定viewForZoomingInScrollView。 如果可能的话,我会避免让UIScrollView成为它自己的委托。 你可以使UIViewController成为UIScrollViewDelegate并让它提供viewForZooming。 或者你可以做一个中间视图的子类,它使用UIScrollView,提供viewForZooming,并转发其他委托方法。

我不认为你可以有两个UIScrollViewDelegate委托直接连接到同一个对象。

你可以做的是让两个代表连锁在一起。 也就是说,你将一个委托人连接到另一个委托人,当它不能直接处理它们时,就把前一个委托人连接到另一个委托人。

无论如何,我想我缺less一点点来充分提出一个解决scheme,即你为什么需要第二个委托,不能总是通过一个委托。 换句话说,我认为可能会有其他devise可以避免需要两名代表。

这是一个优雅的解决scheme,涉及2个代表:

  • 自定义滚动视图类LTInfiniteScrollView子类UIView (不是UIScrollView ),并添加一个UIScrollView作为一个孩子。 LTInfiniteScrollView将自己设置为这个UIScrollView的委托。

  • LTInfiniteScrollView定义了它自己的delegate属性和协议。 由于LTInfiniteScrollView没有UIScrollView子类,因此没有与之冲突的现有delegate属性。