objective Cにおける@class,SEL,IMPなどのフレキシブルなメカニズム(五)
holydancerオリジナルです.もし転載するなら、表示場所に明記してください.
HolydancerのCSDNコラムから回転して、原文の住所:http://blog.csdn.net/holydancer/article/details/7347399
objective cでは、細かいところまで気をつければ、クラスごとに自動的にクラスタイプのisaが生成されます.
Human.h
キーワード:objective-c、objective c、oc、@class、SEL、selector、IMP
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