我正在尝试以下列方式在Objective-C中实现对象的代理:
- (NSMethodSignature*) methodSignatureForSelector:(SEL)sel
{
return [_proxifiedObject methodSignatureForSelector:sel];
}
- (void) forwardInvocation:(NSInvocation *)invocation
{
char returnType = invocation.methodSignature.methodReturnType[0];
if(returnType == '@')
{
id anotherProxy = [[[MyProxy alloc] initWithInvocation:invocation] autorelease];
[invocation setReturnValue:&anotherProxy];
} else {
invocation.target = _proxifiedObject;
[invocation invoke];
}
}
另一个代理应该从此调用构造对象。但是当对象正在构建时,我们应该能够收集并存储对它的调用,以便在构造对象之后有机会处理它们。为实现这一点,我应该实现2个方法:methodSignatureForSelector:和forwardInvocation:。第二个是相当容易的,但首先是问题的全部内容。
我们应该知道能够提供签名的代理对象的类,但是初始化anotherProxy的调用不提供有关返回的对象类的信息。有没有办法获取将使用Apple的Objective-C运行时方法返回的对象类?
更新:
我理解返回对象的实际类可能不同,但可能只有声明该方法的类。如果方法声明为
- (SomeClass*) someMethod;
接口中的我希望得到SomeClass。
更新:
最后我解决了我的问题。解决方案并不优雅,但它“正常”。 我写过这个方法:
static NSMutableDictionary* dictionarySelectorsToSignatures;
+ (NSMethodSignature*) methodSignatureForUnknownClassForSelector: (SEL) sel
{
NSMethodSignature* candidate = [dictionarySelectorsToSignatures objectForKey:[NSNumber numberWithLongLong:(long long) sel]];
if(candidate == nil)
{
int classesCount = objc_getClassList(NULL, 0);
Class* classes = malloc(sizeof(Class) * classesCount);
objc_getClassList(classes, classesCount);
for(int i = 0; i < classesCount; i++)
{
if(class_getClassMethod(classes[i], @selector(instanceMethodSignatureForSelector:)) != NULL)
{
NSMethodSignature* signature = [classes[i] instanceMethodSignatureForSelector:sel];
if(signature != nil)
{
if(candidate != nil)
{
if(![candidate isEqual:signature])
{
return nil;
}
} else {
candidate = signature;
}
}
}
}
if(candidate != nil)
{
[dictionarySelectorsToSignatures setObject:candidate
forKey:[NSNumber numberWithLongLong:(long long) sel]];
}
}
return candidate;
}
如果选择器不是模糊的,则此方法返回选择符,而在其他情况下,返回nil。 它的主要缺点是它不支持在运行时修改类的类/列表,因此只有在所有类都被注册且代码不修改类时才能使用它(使用KVO时可能存在风险!)。
答案 0 :(得分:2)
有没有办法获取将使用Apple的Objective-C运行时方法返回的对象类?
否 - 如果方法返回类类型,则在返回之前无法知道实际的具体类型。由于具体的类类型未知,您无法找出它的方法可能具有的返回类型。
答案 1 :(得分:0)
以下是检查“instance”是否为NSString
的方法if ([instance isKindOfClass:[NSString class]]( {
//do something
}
那好吗?
答案 2 :(得分:0)
您可以获取对象类的实际名称:
e.g。对象foo
NSLog(@"foo is an object of class %@", NSStringFromClass([foo class]));