zblock 结构_Block学习笔记一之结构探究

Block代码实现探究

#import "stdio.h"

int main()

{

void (^blk)(void) = ^{

printf("block/n");

};

blk();

return 0;

};

使用clang命令

clang -rewrite-objc block.m

其中block.m是文件的名字,转换为可读的源代码:block.cpp

block的本质是结构体,基本定义的源码定义如下:

struct __block_impl {

void *isa;

int Flags;

int Reserved;

void *FuncPtr;

};

我们写的

void (^blk)(void) = ^{

printf("block/n");

};

转化成了

//生成对应的结构体声明

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

//构造函数

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {

//&_NSConcreteStackBlock block结构体实例

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

//void 是返回类型 __main_block_func_0是函数名称 *__cself是参数 这里相当于self

// 这个是block里面的方法实现

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

printf("block/n");

}

//根据__main_block_impl_0的大小进行初始化

static struct __main_block_desc_0 {

size_t reserved;

size_t Block_size;

} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

整个main函数转化为:

int main()

{

//使用__main_block_impl_0的构造函数 生成结构体对象并将指针赋值给blk

void (*blk)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

//blk的调用 除去类型转换简化为

// (*blk->impl.FuncPtr)(blk);

((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);

return 0;

};

Block和Objective-C中类的实现原理基本一致,都是使用结构体。

下面是一个基于objc_class的class_t的结构体样式。

struct class_t{

struct class_t *isa;

struct class_t *superclass;

Cache cache;

IMP *vtable;

uintptr_t data_NEVER_USE;

}

Block其实和其他类实现一样,是Objective-C的对象。

附录

clang解析的完整代码(有点多)有兴趣的朋友可以按上面的clang命令自己解析看看。

#ifndef __OBJC2__

#define __OBJC2__

#endif

struct objc_selector; struct objc_class;

struct __rw_objc_super {

struct objc_object *object;

struct objc_object *superClass;

__rw_objc_super(struct objc_object *o, struct objc_object *s) : object(o), superClass(s) {}

};

#ifndef _REWRITER_typedef_Protocol

typedef struct objc_object Protocol;

#define _REWRITER_typedef_Protocol

#endif

#define __OBJC_RW_DLLIMPORT extern

__OBJC_RW_DLLIMPORT void objc_msgSend(void);

__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);

__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);

__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);

__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);

__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass(const char *);

__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass(struct objc_class *);

__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass(const char *);

__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);

__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);

__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);

__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);

#ifdef _WIN64

typedef unsigned long long _WIN_NSUInteger;

#else

typedef unsigned int _WIN_NSUInteger;

#endif

#ifndef __FASTENUMERATIONSTATE

struct __objcFastEnumerationState {

unsigned long state;

void **itemsPtr;

unsigned long *mutationsPtr;

unsigned long extra[5];

};

__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);

#define __FASTENUMERATIONSTATE

#endif

#ifndef __NSCONSTANTSTRINGIMPL

struct __NSConstantStringImpl {

int *isa;

int flags;

char *str;

#if _WIN64

long long length;

#else

long length;

#endif

};

#ifdef CF_EXPORT_CONSTANT_STRING

extern "C" __declspec(dllexport) int __CFConstantStringClassReference[];

#else

__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];

#endif

#define __NSCONSTANTSTRINGIMPL

#endif

#ifndef BLOCK_IMPL

#define BLOCK_IMPL

struct __block_impl {

void *isa;

int Flags;

int Reserved;

void *FuncPtr;

};

// Runtime copy/destroy helper functions (from Block_private.h)

#ifdef __OBJC_EXPORT_BLOCKS

extern "C" __declspec(dllexport) void _Block_object_assign(void *, const void *, const int);

extern "C" __declspec(dllexport) void _Block_object_dispose(const void *, const int);

extern "C" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];

extern "C" __declspec(dllexport) void *_NSConcreteStackBlock[32];

#else

__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);

__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);

__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];

__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];

#endif

#endif

#define __block

#define __weak

#include

struct __NSContainer_literal {

void * *arr;

__NSContainer_literal (unsigned int count, ...) {

va_list marker;

va_start(marker, count);

arr = new void *[count];

for (unsigned i = 0; i < count; i++)

arr[i] = va_arg(marker, void *);

va_end( marker );

};

~__NSContainer_literal() {

delete[] arr;

}

};

extern "C" __declspec(dllimport) void * objc_autoreleasePoolPush(void);

extern "C" __declspec(dllimport) void objc_autoreleasePoolPop(void *);

struct __AtAutoreleasePool {

__AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}

~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}

void * atautoreleasepoolobj;

};

#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)

typedef signed char __int8_t;

typedef unsigned char __uint8_t;

typedef short __int16_t;

typedef unsigned short __uint16_t;

typedef int __int32_t;

typedef unsigned int __uint32_t;

typedef long long __int64_t;

typedef unsigned long long __uint64_t;

typedef long __darwin_intptr_t;

typedef unsigned int __darwin_natural_t;

typedef int __darwin_ct_rune_t;

typedef union {

char __mbstate8[128];

long long _mbstateL;

} __mbstate_t;

typedef __mbstate_t __darwin_mbstate_t;

typedef long int __darwin_ptrdiff_t;

typedef long unsigned int __darwin_size_t;

typedef __builtin_va_list __darwin_va_list;

typedef int __darwin_wchar_t;

typedef __darwin_wchar_t __darwin_rune_t;

typedef int __darwin_wint_t;

typedef unsigned long __darwin_clock_t;

typedef __uint32_t __darwin_socklen_t;

typedef long __darwin_ssize_t;

typedef long __darwin_time_t;

typedef __int64_t __darwin_blkcnt_t;

typedef __int32_t __darwin_blksize_t;

typedef __int32_t __darwin_dev_t;

typedef unsigned int __darwin_fsblkcnt_t;

typedef unsigned int __darwin_fsfilcnt_t;

typedef __uint32_t __darwin_gid_t;

typedef __uint32_t __darwin_id_t;

typedef __uint64_t __darwin_ino64_t;

typedef __darwin_ino64_t __darwin_ino_t;

typedef __darwin_natural_t __darwin_mach_port_name_t;

typedef __darwin_mach_port_name_t __darwin_mach_port_t;

typedef __uint16_t __darwin_mode_t;

typedef __int64_t __darwin_off_t;

typedef __int32_t __darwin_pid_t;

typedef __uint32_t __darwin_sigset_t;

typedef __int32_t __darwin_suseconds_t;

typedef __uint32_t __darwin_uid_t;

typedef __uint32_t __darwin_useconds_t;

typedef unsigned char __darwin_uuid_t[16];

typedef char __darwin_uuid_string_t[37];

struct __darwin_pthread_handler_rec {

void (*__routine)(void *);

void *__arg;

struct __darwin_pthread_handler_rec *__next;

};

struct _opaque_pthread_attr_t {

long __sig;

char __opaque[56];

};

struct _opaque_pthread_cond_t {

long __sig;

char __opaque[40];

};

struct _opaque_pthread_condattr_t {

long __sig;

char __opaque[8];

};

struct _opaque_pthread_mutex_t {

long __sig;

char __opaque[56];

};

struct _opaque_pthread_mutexattr_t {

long __sig;

char __opaque[8];

};

struct _opaque_pthread_once_t {

long __sig;

char __opaque[8];

};

struct _opaque_pthread_rwlock_t {

long __sig;

char __opaque[192];

};

struct _opaque_pthread_rwlockattr_t {

long __sig;

char __opaque[16];

};

struct _opaque_pthread_t {

long __sig;

struct __darwin_pthread_handler_rec *__cleanup_stack;

char __opaque[8176];

};

typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t;

typedef struct _opaque_pthread_cond_t __darwin_pthread_cond_t;

typedef struct _opaque_pthread_condattr_t __darwin_pthread_condattr_t;

typedef unsigned long __darwin_pthread_key_t;

typedef struct _opaque_pthread_mutex_t __darwin_pthread_mutex_t;

typedef struct _opaque_pthread_mutexattr_t __darwin_pthread_mutexattr_t;

typedef struct _opaque_pthread_once_t __darwin_pthread_once_t;

typedef struct _opaque_pthread_rwlock_t __darwin_pthread_rwlock_t;

typedef struct _opaque_pthread_rwlockattr_t __darwin_pthread_rwlockattr_t;

typedef struct _opaque_pthread_t *__darwin_pthread_t;

typedef int __darwin_nl_item;

typedef int __darwin_wctrans_t;

typedef __uint32_t __darwin_wctype_t;

typedef __darwin_va_list va_list;

typedef __darwin_size_t size_t;

extern "C" {

int renameat(int, const char *, int, const char *) __attribute__((availability(macosx,introduced=10.10)));

int renamex_np(const char *, const char *, unsigned int) __attribute__((availability(macosx,introduced=10.12))) __attribute__((availability(ios,introduced=10.0))) __attribute__((availability(tvos,introduced=10.0))) __attribute__((availability(watchos,introduced=3.0)));

int renameatx_np(int, const char *, int, const char *, unsigned int) __attribute__((availability(macosx,introduced=10.12))) __attribute__((availability(ios,introduced=10.0))) __attribute__((availability(tvos,introduced=10.0))) __attribute__((availability(watchos,introduced=3.0)));

}

typedef __darwin_off_t fpos_t;

struct __sbuf {

unsigned char *_base;

int _size;

};

struct __sFILEX;

typedef struct __sFILE {

unsigned char *_p;

int _r;

int _w;

short _flags;

short _file;

struct __sbuf _bf;

int _lbfsize;

void *_cookie;

int (* _Nullable _close)(void *);

int (* _Nullable _read) (void *, char *, int);

fpos_t (* _Nullable _seek) (void *, fpos_t, int);

int (* _Nullable _write)(void *, const char *, int);

struct __sbuf _ub;

struct __sFILEX *_extra;

int _ur;

unsigned char _ubuf[3];

unsigned char _nbuf[1];

struct __sbuf _lb;

int _blksize;

fpos_t _offset;

} FILE;

extern "C" {

extern FILE *__stdinp;

extern FILE *__stdoutp;

extern FILE *__stderrp;

}

extern "C" {

void clearerr(FILE *);

int fclose(FILE *);

int feof(FILE *);

int ferror(FILE *);

int fflush(FILE *);

int fgetc(FILE *);

int fgetpos(FILE * , fpos_t *);

char *fgets(char * , int, FILE *);

FILE *fopen(const char * __filename, const char * __mode) __asm("_" "fopen" );

int fprintf(FILE * , const char * , ...) __attribute__((__format__ (__printf__, 2, 3)));

int fputc(int, FILE *);

int fputs(const char * , FILE * ) __asm("_" "fputs" );

size_t fread(void * __ptr, size_t __size, size_t __nitems, FILE * __stream);

FILE *freopen(const char * , const char * ,

FILE * ) __asm("_" "freopen" );

int fscanf(FILE * , const char * , ...) __attribute__((__format__ (__scanf__, 2, 3)));

int fseek(FILE *, long, int);

int fsetpos(FILE *, const fpos_t *);

long ftell(FILE *);

size_t fwrite(const void * __ptr, size_t __size, size_t __nitems, FILE * __stream) __asm("_" "fwrite" );

int getc(FILE *);

int getchar(void);

char *gets(char *);

void perror(const char *);

int printf(const char * , ...) __attribute__((__format__ (__printf__, 1, 2)));

int putc(int, FILE *);

int putchar(int);

int puts(const char *);

int remove(const char *);

int rename (const char *__old, const char *__new);

void rewind(FILE *);

int scanf(const char * , ...) __attribute__((__format__ (__scanf__, 1, 2)));

void setbuf(FILE * , char * );

int setvbuf(FILE * , char * , int, size_t);

int sprintf(char * , const char * , ...) __attribute__((__format__ (__printf__, 2, 3))) __attribute__((__availability__(swift, unavailable, message="Use snprintf instead.")));

int sscanf(const char * , const char * , ...) __attribute__((__format__ (__scanf__, 2, 3)));

FILE *tmpfile(void);

__attribute__((__availability__(swift, unavailable, message="Use mkstemp(3) instead.")))

__attribute__((deprecated("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead.")))

char *tmpnam(char *);

int ungetc(int, FILE *);

int vfprintf(FILE * , const char * , va_list) __attribute__((__format__ (__printf__, 2, 0)));

int vprintf(const char * , va_list) __attribute__((__format__ (__printf__, 1, 0)));

int vsprintf(char * , const char * , va_list) __attribute__((__format__ (__printf__, 2, 0))) __attribute__((__availability__(swift, unavailable, message="Use vsnprintf instead.")));

}

extern "C" {

char *ctermid(char *);

FILE *fdopen(int, const char *) __asm("_" "fdopen" );

int fileno(FILE *);

}

extern "C" {

int pclose(FILE *) __attribute__((__availability__(swift, unavailable, message="Use posix_spawn APIs or NSTask instead.")));

FILE *popen(const char *, const char *) __asm("_" "popen" ) __attribute__((__availability__(swift, unavailable, message="Use posix_spawn APIs or NSTask instead.")));

}

extern "C" {

int __srget(FILE *);

int __svfscanf(FILE *, const char *, va_list) __attribute__((__format__ (__scanf__, 2, 0)));

int __swbuf(int, FILE *);

}

inline __attribute__ ((__always_inline__)) int __sputc(int _c, FILE *_p) {

if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))

return (*_p->_p++ = _c);

else

return (__swbuf(_c, _p));

}

extern "C" {

void flockfile(FILE *);

int ftrylockfile(FILE *);

void funlockfile(FILE *);

int getc_unlocked(FILE *);

int getchar_unlocked(void);

int putc_unlocked(int, FILE *);

int putchar_unlocked(int);

int getw(FILE *);

int putw(int, FILE *);

__attribute__((__availability__(swift, unavailable, message="Use mkstemp(3) instead.")))

__attribute__((deprecated("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead.")))

char *tempnam(const char *__dir, const char *__prefix) __asm("_" "tempnam" );

}

typedef __darwin_off_t off_t;

extern "C" {

int fseeko(FILE * __stream, off_t __offset, int __whence);

off_t ftello(FILE * __stream);

}

extern "C" {

int snprintf(char * __str, size_t __size, const char * __format, ...) __attribute__((__format__ (__printf__, 3, 4)));

int vfscanf(FILE * __stream, const char * __format, va_list) __attribute__((__format__ (__scanf__, 2, 0)));

int vscanf(const char * __format, va_list) __attribute__((__format__ (__scanf__, 1, 0)));

int vsnprintf(char * __str, size_t __size, const char * __format, va_list) __attribute__((__format__ (__printf__, 3, 0)));

int vsscanf(const char * __str, const char * __format, va_list) __attribute__((__format__ (__scanf__, 2, 0)));

}

typedef __darwin_ssize_t ssize_t;

extern "C" {

int dprintf(int, const char * , ...) __attribute__((__format__ (__printf__, 2, 3))) __attribute__((availability(macosx,introduced=10.7)));

int vdprintf(int, const char * , va_list) __attribute__((__format__ (__printf__, 2, 0))) __attribute__((availability(macosx,introduced=10.7)));

ssize_t getdelim(char ** __linep, size_t * __linecapp, int __delimiter, FILE * __stream) __attribute__((availability(macosx,introduced=10.7)));

ssize_t getline(char ** __linep, size_t * __linecapp, FILE * __stream) __attribute__((availability(macosx,introduced=10.7)));

}

extern "C" {

extern const int sys_nerr;

extern const char *const sys_errlist[];

int asprintf(char ** , const char * , ...) __attribute__((__format__ (__printf__, 2, 3)));

char *ctermid_r(char *);

char *fgetln(FILE *, size_t *);

const char *fmtcheck(const char *, const char *);

int fpurge(FILE *);

void setbuffer(FILE *, char *, int);

int setlinebuf(FILE *);

int vasprintf(char ** , const char * , va_list) __attribute__((__format__ (__printf__, 2, 0)));

FILE *zopen(const char *, const char *, int);

FILE *funopen(const void *,

int (* _Nullable)(void *, char *, int),

int (* _Nullable)(void *, const char *, int),

fpos_t (* _Nullable)(void *, fpos_t, int),

int (* _Nullable)(void *));

}

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

printf("block/n");

}

static struct __main_block_desc_0 {

size_t reserved;

size_t Block_size;

} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

int main()

{

void (*blk)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);

return 0;

};

static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO = { 0, 2 };

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值