Runtime-原理と応用
2825 ワード
実行時前提で#importをインポートする必要があります
誰が動作し、接頭辞は誰ですか. コンパイラにヒントを与える:NO に設定する. oc最下位runtimeの実装 を参照
オブジェクトメソッドはクラスに格納され、クラスメソッドはメタクラスに格納されます. クラス呼び出しのメソッドはruntimeの下部でクラスをクラスオブジェクトに変換してメソッドを呼び出します. 各クラスにはメソッドリスト(実装済みメソッド)があります.
メタクラスはクラスメソッドリスト を保存する.メタクラス(meteClass)はクラスであり、オブジェクト でもある.
適用シーン:プライベートメソッドを呼び出す(呼び出す方法がある場合はクラッシュする)
アプリケーションシーン:システムメソッドの本来の機能が足りない可能性があり、既存の機能を維持して新しい機能を拡張する 分類ではloadメソッドを書き換え,loadメソッドではシステムの元のメソッドと新しいメソッドをruntimeで 交換する.
アプリケーションシーン:怠惰なロードメカニズム、いくつかの方法は長い間呼び出されず、クラスをメモリにロードするにはリソースを消費し、動的に追加する方法は、使用するときにメモリにロードすることです.
運用シーン:システムのクラスに属性6.1を追加する.分類6.2を生成する.set getメソッド を書き換える
1.runtimeの使い方
TARGETS - Build Settings - msg - NO
cd
clang -rewrite-objc
2.1.オブジェクトがどのように対応するメソッドを見つけて呼び出すか:
1. isa
2.
3.
2.2.クラスは、クラスメソッドを呼び出します。
1. isa
2.
3.
4. ,
3.メッセージメカニズム
Person *p = [[Person alloc] init];
//
objc_msgSend(p, @selector(eat));
//
objc_msgSend(p, @selector(eat), 20);
4.交換方法
+ (void)load
{
Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
// xmg_imageNamed
Method xmg_imageNamedMethod = class_getClassMethod(self, @selector(xmg_imageNamed:));
// :runtimec
method_exchangeImplementations(imageNamedMethod, xmg_imageNamedMethod);
}
5.メソッドの追加
#import "ViewController.h"
#import "Person.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat)];
[p performSelector:@selector(run:) withObject:@1];
}
@end
#import "Person.h"
#import
@implementation Person
+ (BOOL)resolveInstanceMethod:(SEL)sel{
if(sel == NSSelectorFromString(@"eat")){
class_addMethod(self, sel, (IMP)eat, "v@:@");
return YES;
}
if(sel == NSSelectorFromString(@"run:")){
class_addMethod(self, sel, (IMP)(run), "v@:@");
return YES;
}
return [super resolveInstanceMethod:sel];
}
void eat(id self, SEL _cmd){
NSLog(@" ?");
}
void run(id self, SEL _cmd, NSNumber *num){
NSLog(@" %@ ", num);
}
@end
6.属性の追加:
@interface NSObject (Property)
@property NSString *name;
@end
- (void)setName:(NSString *)name{
objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)name{
return objc_getAssociatedObject(self, @"name");
}