gpt4 book ai didi

objective-c - NSInspiration 和 super

转载 作者:行者123 更新时间:2023-12-03 16:23:25 26 4
gpt4 key购买 nike

为什么不能将super设置为NSInitation的目标?

还有其他方法可以实现这一点吗?

最佳答案

虽然它看起来很像 self,但 super 并不是一个变量。这是一个关键字。例如,这是一个语法错误:

- (void)log {
NSLog(@"%@", super);
}

“super”关键字只能用作消息的接收者,在这种情况下意味着避免正常的多态分派(dispatch)并调用属于相关代码的父类(super class)的方法。

如果你有这样的事情:

@interface Vehicle : NSObject
@end

@interface Car : Vehicle
@end

@implementation Vehicle
- (void)log {
NSLog(@"-[Vehicle log] invoked on an instance of %@", NSStringFromClass([self class]));
}
@end


@implementation Car
- (void)log {
NSLog(@"-[Vehicle log] invoked on an instance of %@", NSStringFromClass([self class]));
}
@end

当接收者是 Car 的实例时,这是一种获取 -[Vehicle log] 的方法。

@implementation Car

- (void)log {
NSLog(@"-[Vehicle log] invoked on an instance of %@", NSStringFromClass([self class]));
}

- (void)runVehiclesLog {
[super log];
}

- (void)runInvocationThatTargetsVehicle {
SEL selector = @selector(runVehiclesLog);
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
[invocation setTarget:self];
[invocation setSelector:selector];
[invocation invoke];
}
@end

如果您无法编辑类,但仍需要执行此操作,那么您可以使用 +[NSObject instanceMethodForSelector:] 代替 NSInitation,如下所示:

typedef void (*MyVoidMethodWithNoArgs)(id receiver, SEL selector);
int main(int argc, const char * argv[]) {
@autoreleasepool {
Car *car = [[Car alloc] init];
MyVoidMethodWithNoArgs imp = (MyVoidMethodWithNoArgs)[Vehicle instanceMethodForSelector:@selector(log)];
imp(car, @selector(log));
}
return 0;
}

在第二种情况下,您也避免了动态分派(dispatch),而是向下获取指向实现上面定义的方法的 c 函数的指针。在调用之前,将 instanceMethodForSelector: 的结果强制转换为具有正确原型(prototype)的函数非常重要。此外,选择器参数并不是选择方法,而是将第二个隐藏参数填充到所有 Objective-C 函数,并调用选择器。如果您在对 imp 的调用中传递了不同的选择器,代码仍然会运行,但会违反约定。

关于objective-c - NSInspiration 和 super,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9831914/

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