gpt4 book ai didi

objective-c - 转发调用 : the return value gets lost

转载 作者:可可西里 更新时间:2023-11-01 04:27:39 26 4
gpt4 key购买 nike

我想在我的 SZNUnmanagedReference 类上使用消息转发。它具有以下属性:

@property (nonatomic, strong) NSSet *authors;
@property (nonatomic, strong) SZNReferenceDescriptor *referenceDescriptor;

基本上,当 UnmanagedReference 的实例收到消息 authorsString 时,它应该将它转发给 referenceDescriptor,它有一个名为 - (NSString *)authorsStringWithSet 的方法:(NSSet *)作者

所以,我在 SZNUnmanagedReference.m 中写了这个:

- (void)forwardInvocation:(NSInvocation *)anInvocation {

SEL aSelector = anInvocation.selector;

if ([NSStringFromSelector(aSelector) isEqualToString:NSStringFromSelector(@selector(authorsString))]) {
NSMethodSignature *signature = [self.referenceDescriptor methodSignatureForSelector:@selector(authorsStringWithSet:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
NSSet *authors = [NSSet setWithSet:self.authors];
[invocation setSelector:@selector(authorsStringWithSet:)];
[invocation setArgument:&authors atIndex:2];
[invocation setTarget:self.referenceDescriptor];

[invocation invoke];
} else {
[self doesNotRecognizeSelector:aSelector];
}
}

- (BOOL)respondsToSelector:(SEL)aSelector {
if ([super respondsToSelector:aSelector]) {
return YES;
} else if ([NSStringFromSelector(aSelector) isEqualToString:NSStringFromSelector(@selector(authorsString))] && [self.referenceDescriptor respondsToSelector:@selector(authorsStringWithSet:)]) {
return YES;
} else {
return NO;
}
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (!signature) {
signature = [self.referenceDescriptor methodSignatureForSelector:@selector(authorsStringWithSet:)];
}
return signature;
}

一切似乎都正常,SZNReferenceDescriptor 类中的代码得到执行。但是,我不知道如何取回 authorsString。如果我对文档的理解正确,我认为 referenceDescriptor 应该将结果发送回消息的原始发件人。但这似乎不起作用。在我的测试类中,[unmanagedReference authorsString] 返回 nil

最佳答案

问题是您正在构建一个新的 NSInvocation 对象,其返回值在需要它的位置(消息调度“堆栈”的“顶部”)不可访问。运行时只知道它为您创建的那个(forwardInvocation: 的参数;这是它将使用其返回值的那个。那么,您所要做的就是设置 它的返回值:

- (void)forwardInvocation:(NSInvocation *)anInvocation {

if (anInvocation.selector == @selector(authorsString)) {
id retVal = [self.referenceDescriptor authorsStringWithSet:self.authors];

[anInvocation setReturnValue:&retVal]; // ARC may require some memory-qualification casting here; I'm compiling this by brain at the moment
} else {
[super forwardInvocation:anInvocation];
}
}

事实上,实际上没有必要创建新的调用;因为您只需要方法的返回值,您可以直接发送消息(如果您只是在 SZNUnmanagedReference 上实现了 authorsString,也可以这样做,而不是使用转发机制)。

另外,请注意,无需将选择器与字符串相互转换来比较它们——SEL 可以使用相等运算符直接进行比较。

关于objective-c - 转发调用 : the return value gets lost,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11457651/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com