intmain() {
void(^testBlock)(void)=^{
printf("i am testBlock");
};
testBlock();
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
struct __block_impl impl;
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
staticstruct__main_block_desc_0 {
size_t reserved;
size_t Block_size;
} __main_block_desc_0_DATA = { 0,sizeof(struct__main_block_impl_0)};
intmain() {
void(*testBlock)(void)=(void(*)())&__main_block_impl_0((void*)__main_block_func_0, &__main_block_desc_0_DATA);
((void(*)(__block_impl *))((__block_impl *)testBlock)->FuncPtr)((__block_impl *)testBlock);
}
struct __block_impl impl;
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
size_t reserved;
size_t Block_size;
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
結構體:
struct__main_block_impl_0 {
//__block_impl
void*isa;
int Flags; int Reserved;
void
*FuncPtr;
//
struct __main_block_desc_0* Desc;
};
|
初始化:
//
isa = &_NSConcreteStackBlock;
Flags = 0;
Reserved=0
FuncPtr =__main_block_func_0;
//
Desc =&__main_block_desc_0_DATA;
|
接下來解釋一下 isa = &_NSConcreteStackBlock;這句話。
Block是OC對象,“id”用來存儲OC對象,id類型也能夠在c語言中聲明:
typedef struct objc_object{
Class isa;
} *id;
id 爲objc_object結構體指針類型。Class的定義如下:
typedef struct objc_class*Class;
Class爲objc_class結構體的指針類型,objc_class結構體在模擬器目錄下/usr/include/objc/runtime.h(導入#import<objc/runtime.h>點擊可進入)中聲明如下(除去無關宏定義):
structobjc_class {
Class isa;
};
objc_class與結構體objc_object的定義相同。但是分別是在類與對象中使用的結構體,下面通過簡單的OC類聲明來驗證一下。
@interfaceMyObject : NSObject
{ int val0; int val1; } @end
基於objc_object結構體,該類的對象的結構體如下:
structMyObject{
Class isa; int val0; int val1; };
類中的實例變量被包含在對象的結構體中,類生成對象意味着類生成該類的對象的各個結構體實例,通過成員變量isa保持該類的結構體實例指針(即isa爲指向所屬類的結構體實例的指針),如下圖:
各類的結構體就是基於objc_class結構體的class_t結構體,class_t結構體在objc4運行時庫的聲明如下:
structclass_t{
struct class_t *isa; struct class_t *superclass; Cache cache; IMP *vtable; uintptr_t data_NEVER_USE; };
在OC中,各個類的結構體實例均生成並保持各個類的class_t結構體實例。該實例存有類的相關信息,包括持有聲明的成員變量、方法的名稱、方法的實現(函數指針)、屬性即父類的指針,並被OC運行時庫所使用。
|