簡體   English   中英

將字符串轉換為“方法”-在類方法調用中使用

[英]Converting a String to a “Method” - To be used in a Class Method call

我熟悉NSSelectorFromString函數,通過它我們可以從字符串創建新的SEL

問題是我不能使用它來執行Class Method調用,因為performSelector方法僅適用於實例作為接收者。

我需要某些功能,例如:

NSString* colorName = colorsArray[num];
NSString* methodName = [NSString stringWithFormat:@"%@Color", colorName]; //will create blueColor or redColor, etc...
SEL colorMethod = NSSelectorFromString(methodName);
self.view.backgroundColor = [UIColor performSelector:colorMethod]; //this is not valid... since NSObject only has performSelector as an Instance method...

還有另一種方法來保存表示方法的運行時變量,該方法可以充當類方法並可以從NSString創建?

還是通過選擇器向班級發送消息的方式?

問題是我不能使用它來執行Class Method調用,因為performSelector方法僅適用於實例作為接收者。

錯了 是什么讓您認為UIColor類對象不是“實例”? 類對象是對象,這意味着它們是某個類的“實例”。 類對象是其根類(某些子類)的實例,在UIColor的情況下,其是NSObject (換句話說, UIColor類對象也是NSObject並支持所有NSObject實例方法。)

如果您想了解其工作原理,則每個類對象都是元類的實例。 每個類都有其自己的元類,並且元類在其類之后具有繼承性(即,如果A是B的超類,則A的元類是B的元類的超類)。 最后,根類的元類繼承自根類本身(因此NSObject的元類繼承自NSObject )。 這意味着繼承了類方法,此外,具有該根類的所有類都將根類(在本例中為NSObject )的實例方法作為類方法繼承。

只需在類上調用performSelector

#import <Foundation/Foundation.h>

@interface T : NSObject
+ (NSString*)foo;
+ (NSString*)redColor;
@end

@implementation T
+ (NSString*)foo {
    return @"bar";
}
+ (NSString*)redColor {
    return @"RED";
}
@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        id tclass = [T class];
        NSLog(@"%@", [tclass performSelector:@selector(foo)]);
        NSLog(@"%@", [tclass performSelector:@selector(redColor)]);

        SEL sel = NSSelectorFromString(@"redColor");
        NSLog(@"%@", [tclass performSelector:sel]);

    }
}

摘自《 可可基礎指南》 (已過時,但本部分仍然有效):

運行時系統以特殊方式處理在根類中定義的方法。 在根類中定義的實例方法既可以由實例也可以由類對象執行。 因此,所有類對象都可以訪問在根類中定義的實例方法。

Foundation框架提供了兩個根類:NSObject和NSProxy。 NSObject的方法記錄為– performSelector:但是由於它是根類,因此任何子類都可以將其用作類方法。 例如: +[UIColor performSelector:]-[UIColor performSelector:]工作。 在newacct的答案中給出了運行時級別的解釋。

一個調用類方法,另一個調用實例方法。 例:

#import <Foundation/Foundation.h>

@interface A : NSObject
@end

@implementation A
+(void) x { NSLog(@"class method"); }
-(void) x { NSLog(@"instance method"); }
@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        [A performSelector:@selector(x)];
        [[A new] performSelector:@selector(x)];
    }
}

打印

class method
instance method

您還可以使用NSInvocation:

SEL sel = NSSelectorFromString(@"whiteColor");
NSMethodSignature *sig = [UIColor methodSignatureForSelector:sel];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setSelector:sel];
[invocation setTarget:[UIColor class]];
CFTypeRef retVal;
[invocation invoke];
[invocation getReturnValue:&retVal];
NSLog(@"retVal: %@", retVal);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM