Object-C Runtime
5041 ワード
Object-C Runtime
Object-Cは動的言語であり,その動的特性はRuntimeによって実現される.主にC言語で、一部のアセンブリの内容もあります.Swiftはこのメカニズムがなく、普段開発してもほとんど使えないので、ずっと注目していませんでした.しかし、面接の時、特にアリの技術は、この内容を聞くのが好きです.現在、ネット上にもこの良い文章があるので、勉強してみましょう.
メッセージング
多くの言語、例えばCでは、メモリのある点にジャンプしてコードを実行する方法を呼び出します.コンパイル時に決定されるので、ダイナミックな特性はありません.一方、Objective-Cでは、
実際、コンパイル時にObjective-C関数呼び出しの構文は、Cの関数呼び出し-
objc_msgSend(array, @selector(insertObject:atIndex:), foo, 5);```
関連データ構造
typedef struct objc_class *Class;
Object-Cは動的言語であり,その動的特性はRuntimeによって実現される.主にC言語で、一部のアセンブリの内容もあります.Swiftはこのメカニズムがなく、普段開発してもほとんど使えないので、ずっと注目していませんでした.しかし、面接の時、特にアリの技術は、この内容を聞くのが好きです.現在、ネット上にもこの良い文章があるので、勉強してみましょう.
メッセージング
多くの言語、例えばCでは、メモリのある点にジャンプしてコードを実行する方法を呼び出します.コンパイル時に決定されるので、ダイナミックな特性はありません.一方、Objective-Cでは、
[object foo]
構文はfooという方法のコードをすぐに実行しません.実行時にobjectにfooというメッセージを送信します.このメッセージは、objectによって処理されるか、別のオブジェクトに転送されるか、受信していないふりをして相手にしないかもしれません.複数の異なるメッセージは、同じ方法に対応して実装されてもよい.これらはすべてプログラムの実行時に決定されます.実際、コンパイル時にObjective-C関数呼び出しの構文は、Cの関数呼び出し-
objc_msgSend()
に翻訳されます.たとえば、次の2行のコードは等価です.[array insertObject:foo atIndex:5];```
objc_msgSend(array, @selector(insertObject:atIndex:), foo, 5);```
関連データ構造
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};```
typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
if !OBJC2
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
endif
} OBJC2_UNAVAILABLE;
struct objc_method_list {
struct objc_method_list *obsolete OBJC2_UNAVAILABLE;
int method_count OBJC2_UNAVAILABLE;
ifdef LP64
int space OBJC2_UNAVAILABLE;
endif
/* variable length structure */
struct objc_method method_list[1] OBJC2_UNAVAILABLE;
}
struct objc_method {
SEL method_name OBJC2_UNAVAILABLE;
char *method_types OBJC2_UNAVAILABLE;
IMP method_imp OBJC2_UNAVAILABLE;
} ```
struct objc_cache {
unsigned int mask /* total = mask + 1 */ OBJC2_UNAVAILABLE;
unsigned int occupied OBJC2_UNAVAILABLE;
Method buckets[1] OBJC2_UNAVAILABLE;
};```
struct objc_protocol_list {
struct objc_protocol_list *next;
long count;
Protocol *list[1];
};```
struct objc_ivar_list {
int ivar_count OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_ivar ivar_list[1] OBJC2_UNAVAILABLE;
}```
#
```objc_msgSend(obj, foo)``` :
1. , obj isa class ;
1. class method list foo ;
1. class foo, superclass ;
1. foo , IMP .
, 。 class 20% , 80% 。 ```objc_method_list``` 。 , 。 ```objc_class``` ```objc_cache``` - foo , foo ```method_name``` key ,```method_imp``` value 。 foo , cache , ```objc_method_list```.
#
, foo ? , unrecognized selector sent to … 。 ,Objective-C :
1. Method resolution
1. Fast forwarding
1. Normal forwarding
#
Objective-C :
1. dispatch table 。 , IMP ;
1. ,Runtime ```+resolveInstanceMethod:``` ```+resolveClassMethod: ``` resolve ;
1. resolve NO,Runtime ```-forwardingTargetForSelector:``` ;
1. , Runtime ```-methodSignatureForSelector:``` ```-forwardInvocation: ``` 。 ```-invokeWithTarget: ``` ```-doesNotRecognizeSelector:``` 。
#
[ ](http://tech.glowing.com/cn/objective-c-runtime/)
[Method Swizzling](http://tech.glowing.com/cn/method-swizzling-aop/)
[Objective-C Runtime](http://justsee.iteye.com/blog/2163777)
[iOS runtime ](http://blog.csdn.net/mr_yong/article/details/50330151)
[iOS runtime ](http://www.jianshu.com/p/364eab29f4f5)
[ RunLoop](http://blog.ibireme.com/2015/05/18/runloop/)