我遇到了一个案例,CaptureScreenshot()
/ UITableView
委托由代理对象(不是UICollectionView
转发,只是常规对象)。
根据特定的委托方法,代理会将其转发给实际响应该方法的2个对象之一。
给定一个委托回调,我想知道响应方法调用的“真实”实例。
代理代码如下:
NSProxy
我的代码如下:
给定一个委托方法,我想知道哪个实例正在响应:
@implementation DelegateSplitter
- (instancetype)initWithFirstDelegate:(id<NSObject>)firstDelegate secondDelegate:(id<NSObject>)secondDelegate
{
if(self = [super init])
{
_firstDelegate = firstDelegate;
_secondDelegate = secondDelegate;
}
return self;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
SEL aSelector = [anInvocation selector];
if([self.firstDelegate respondsToSelector:aSelector])
{
[anInvocation invokeWithTarget:self.firstDelegate];
}
if([self.secondDelegate respondsToSelector:aSelector])
{
[anInvocation invokeWithTarget:self.secondDelegate];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature *first = [(NSObject *)self.firstDelegate methodSignatureForSelector:aSelector];
NSMethodSignature *second = [(NSObject *)self.secondDelegate methodSignatureForSelector:aSelector];
if(first)
{
return first;
}
else if(second)
{
return second;
}
return nil;
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
if([self.firstDelegate respondsToSelector:aSelector] || [self.secondDelegate respondsToSelector:aSelector])
{
return YES;
}
else
{
return NO;
}
}
@end
修改
当前的黑客行为(想要更全面的东西):
使模拟对象调用转发器并获取目标对象
// delegate is an instance of DelegateSplitter
id <UITableViewDelegate> delegate = tv.delegate;
SEL didSelectItemSelector = @selector(collectionView:didSelectItemAtIndexPath:);
if ([delegate respondsToSelector:didSelectItemSelector]) {
// the delegate splitter doesn't forward the call
...
return;
}
// the delegate (proxy) forwards the method to a different instance
if (![delegate.class instancesRespondToSelector:didSelectItemSelector]) {
// the delegate responds to selector but the class instances themselves do not respond to the selector. This is possible if the delegate is forwarding all invocations to a different object
NSObject *d = (NSObject *)delegate;
NSMethodSignature *ms = [d methodSignatureForSelector:didSelectItemSelector];
if (ms) {
** I WANT TO GET THE INSTANCE WHICH IS RESPONDING**
????
HOW DO I GET IT
?????
}
}