objective Cにおける@class,SEL,IMPなどのフレキシブルなメカニズム(五)


holydancerオリジナルです.もし転載するなら、表示場所に明記してください.
HolydancerのCSDNコラムから回転して、原文の住所:http://blog.csdn.net/holydancer/article/details/7347399
objective cでは、細かいところまで気をつければ、クラスごとに自動的にクラスタイプのisaが生成されます.
@interface NSObject <NSObject> {
     Class    isa;
 }
isaは何ですか?クラスは何ですか?クラスの定義を見つけたら次のように分かります.
typedefstruct objc_class *Class;
そして、objcクラスの前の定義はまた次の通りです.現在は閉鎖されていると言われていますが、修正されたかどうかは分かりません.
struct objc_class {
     Class isa;
     
     Class super_class;
     
     const char *name;
     
     long version;
     long info;
     
     long instance_size;
     struct objc_ivar_list *ivars;
     struct objc_method_list **methodLists; 
     
     struct objc_cache *cache;
     struct objc_protocol_list *protocols;   
 }
そこで、私たちは頷きました.is a、isa pointerは、ポインタです.(インターネットの資料によって、これは一番近い事実です.信じても信じなくても、とにかく私は信じてもいいです.).各クラスには、一つのclassタイプのポインタisaがあります.NSObjectから引き継ぎ、相続関係、方法変数などの情報はisaに保存されます.isaは隠し属性としていで、isaはisaに保存されます.各クラスに自動的に生成されます.この前提があれば、なぜ私たちは@classによって任意の種類に代わることができるのかを説明できます.コードを見ます.
Human.h
#import <Foundation/Foundation.h>

@interface Human : NSObject
-(void)say;
@end
Human.m
#import "Human.h"

@implementation Human
-(void)say
{
    NSLog(@"Human  say  ");
}
@end
メール.h
#import <Foundation/Foundation.h>
#import "Human.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        Class c =NSClassFromString(@"Human");
        [[c new] say];
        //  CLASS   c,    Human 。
    }
    return 0;
}
クラスは他のクラスに柔軟に代えることができます.SELは類似しています.SELの代わりに方法があります.他の方法に便利に代えることができます.クラスにはisa属性がありますので、クラス情報が保存されています.SELは同じクラスでも方法名が同じなら、この二つの方法のIDは同じです.SELはこのIDによってこの方法を見つけます.また、この方法を呼び出すクラスによって固有のアドレスを見つけます.コードを見て説明します.
#import <Foundation/Foundation.h>


#import <Foundation/Foundation.h>

@interface Human : NSObject
-(void)say;
@end
@implementation Human
-(void)say
{
    NSLog(@"Human  say  ");
}
@end
//       human ,     say  
@interface man:NSObject
{}
-(void)say; @end

@implementation man
-(void)say
{
    NSLog(@"man  say  ");
}
@end

//        man ,     say  
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        Class a =NSClassFromString(@"Human");
        Class b =NSClassFromString(@"man");
        //     say      id, sel    ;
        SEL sel = NSSelectorFromString(@"say");
        [[a new] performSelector:sel];
        [[b new] performSelector:sel];
        
        
        
    }
    return 0;
}
結果は以下の通りです
2012-03-13 10:13:24.900 String[2725:403] Human  say  
2012-03-13 10:13:24.901 String[2725:403] man  say  
以上のコードを通して、SELは方法名で結び付けられた後、複数の種類の実例に呼び出されて、いくつかのネット上の資料を探して、説明は全部方法名が同じなら、IDは同じで、住所はまだ違っています.このような効果を実現することができます.このような使い方の利点は、一方では柔軟性が高く、多状態に似ています.一方で、このような使い方は、文字列メソッド名ではなくIDにマッチするので、効率的になります.もう一つの究極の方法があります.直接に対応する方法の住所はこの方法が一番効率的です.コードを見てください.
#import <Foundation/Foundation.h>


#import <Foundation/Foundation.h>

@interface Human : NSObject
-(void)say;
@end
@implementation Human
-(void)say
{
    NSLog(@"Human  say  ");
}
@end
//       human ,     say  
@interface man:NSObject
{}
-(void)say; @end

@implementation man
-(void)say
{
    NSLog(@"man  say  ");
}
@end

//        man ,     say  
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        Human *human =[Human new];
        man *ma=[man new];
        //     say      id, sel    ;
        SEL sel =@selector(say);//      :SEL sel=NSSelectorFromString(@"say");
        IMP imp1 = [human methodForSelector:sel];     
        IMP imp2 = [ma methodForSelector:sel];     

        imp1(human,sel);
        imp2(ma,sel);
        //             ,              ID   ,    ,      SEL  。
        
    }
    return 0;
}
出力文:
2012-03-13 10:35:21.446 String[3763:403] Human  say  
2012-03-13 10:35:21.450 String[3763:403] man  say  
今日はこれらの内容がよく分かりません.自分で理解した方法でもう一度説明します.クラスの代わりにクラスをclassを使って、柔軟性を高めます.いつどんな種類を使うか分かりませんので、方法も同じです.SELは方法の代わりに法律名、ID、住所、同じ方法名、IDも同じです.通常の状況では、方法名によって方法を見つけます.SEL方法でIDに基づいて方法を見つけることができます.IMP方式で直接に住所を見つけることができますが、柔軟性はSEL方法に及ばないです.効率が一番高いです.はい、今日はこれで終わります.
キーワード:objective-c、objective c、oc、@class、SEL、selector、IMP