【问题标题】:How to get the class that the method is defined, not that of the instance that the method is called?如何获取定义方法的类,而不是调用方法的实例的类?
【发布时间】:2012-05-23 22:33:44
【问题描述】:

[self class] 返回被调用方法的实例的Class,但是有没有办法获取该方法定义的Class呢?假设 B 类扩展了 A,并且 b 是 B 的实例,我想要 A 中的方法返回 A 而不是 B,即使从 b 调用也是如此。

已编辑:

我试图创建一个具有 -(void)releaseProperties 方法的 NSObject 类别,该方法获取该类中定义的所有属性,并将非只读对象属性设置为 nil。

- (void)releaseProperties {
    unsigned int c = 0;
    objc_property_t *properties = class_copyPropertyList([self class], &c);

    for(unsigned int i = 0; i < c; i++) {
        objc_property_t property = properties[i];
        NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
        NSString *propertyType = [NSString stringWithUTF8String:property_getAttributes(property)];

        if([propertyType hasPrefix:@"T@"] // is an object
           && [propertyType rangeOfString:@",R,"].location == NSNotFound // not readonly
           ) {
            [self setValue:nil forKey:propertyName];
            NSLog(@"%@.%@ = %@", NSStringFromClass(cls), propertyName, [self valueForKey:propertyName]);
        }
    }
    free(properties);
}

我想在 dealloc 方法中使用这个方法,但是 class_copyPropertyList([self class], &c) 不会返回定义在它的超类中的属性,所以 super-dealloc 链不能正常工作。因此,我不想传递 [self 类],而是传递正在调用特定 dealloc 方法的类。

【问题讨论】:

    标签: objective-c ios reflection


    【解决方案1】:

    我认为没有直接的方法可以做到这一点,但是您可以使用当前类调用class_getMethodImplementation_stret 来获取将要调用的方法的函数指针。然后遍历你的超类,用它们调用相同的函数,直到它返回不同的东西。前一个超类将为您的类提供实现。

    编辑:抱歉,我可能误读了这个问题。如果您正在寻找定义具有该签名的方法的层次结构中的第一个超类,那么您可以遍历调用respondsToSelector: 的超类,直到其中一个没有。我上面描述的方法是找到提供被继承的实现的超类,而不是定义

    例如,A 类可以定义foo:,然后B 类(A 的子类)可以覆盖它,然后C 类(B 的子类)可以问foo: 来自哪里。如果你想要提供定义的类,你想要A,并且应该使用我描述的第二种方法。如果你想要提供实现的类,你想要B,并且应该使用我描述的第一种方法。

    【讨论】:

    • 这可行。您必须链接到 libobjc.A.dylib#import "objc/runtime.h" 才能使用 class_getMethodImplementation_stret。祝你好运。
    【解决方案2】:

    我觉得[super class] 可能适合你。

    如果你在 B 中调用“[super ...”(用你想调用的任何内容填写空白),你将调用 A 中的一个方法。

    【讨论】:

    • 我认为这不适用于两个以上的抽象层。
    • 嗯。我 +1 了这个(非常有趣的)问题,所以它会得到更多关注,但也许我误解了 Taketo 的要求?
    【解决方案3】:

    A 类可以提供如下方法:

    - (Class) classA
    {
        return [A class];
    }
    

    这是不可概括的,但你的问题坚持一个不可概括的答案。

    这是一件很奇怪的事情。它表明您的设计存在问题。我可以问你为什么想要它吗?你想解决什么问题?

    【讨论】:

    • 您可以将类作为参数传递给-releaseProperties 方法。在调用者中,比如说-[MyClass dealloc],它会做[self releaseProperties:[MyClass class]]-releaseProperties 肯定无法自行判断哪个方法调用了它以及哪个类定义了该方法。
    • 谢谢,我认为这是最好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多