oc block潜入研究

先放出:官方文档

要想弄懂block的实现方式,我们要从c++入手
先总结:block=函数指针+结构体+简单工厂模式
为什么这么说?

首先,不熟悉c++的需要弄懂几个语法

万能的指针
oc万年都用不上的结构体

万能的指针

指针在熟悉不过了,oc经常使用,那么什么是万能指针?
原则上万能指针是可以指向任何地址的泛型指针;没有类型,胜似有类型,武学最高宗旨,打造无招胜有招的无名招式;

万能的指针:可分为两类

万能的对象指针 void* p
万能的方法指针 void (*p)(void)

万能的对象指针

NSString *s = @"cctv";
//万能指针p   桥接转换对象s
void *p = (__bridge void *)s;
//对象c         桥接转换对象p
NSString *c = (__bridge NSString *)p;
NSLog(@"c=%@", c);
//输出
c=cctv

万能的方法指针:
1、oc里面可以把方法当参数传递和使用,例如

- (void)superMethod:(SEL)selector

2、oc里面调用方法

((int(*)(id, SEL, NSString *, int))((void *)objc_msgSend))(self, selector, @"cctv", 1);

那么C++呢,C++也有方法处理,而且更简单
3、c++的方法指针

void(*p)(void)

这些是基础,需要记忆

oc万年都用不上的结构体

从c++方向了解 block的实现模式
1、block简单代码

    void(^bk)(void) = ^() {
        printf("@");
    };
    bk();

2、把oc编译成c++, clang实现,网上大堆例子,复制就好

clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk -rewrite-objc TestBlock.m

3、美化后的c++代码,可以直接运行的哦

extern "C"  void *_NSConcreteStackBlock[32];
struct __block_impl {
    void *isa;
    int Flags;
    int Reserved;
    void *FuncPtr;
};//block 结构体

struct block_method {
    struct __block_impl impl;
    struct block_data_0* Desc;
    block_method(void *fp, struct block_data_0 *desc, int flags=0) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
    }//构造函数构造内,赋值了系统block的相关信息
};//自定义block结构体
static void block_func() {//自定义block的执行函数
    printf("@");
}

static struct block_data_0 {//系统定义的block数据结构体,已初始化
    size_t reserved;
    size_t Block_size;
} block_data = { 0, sizeof(struct block_method)};

static void test() {
//系统的强转代码,强转太多,容易看蒙
//    ((void (*)())&block_method((void *)block_func, &block_data));
//    void(*bk)(void) = ((void (*)())&block_method((void *)block_func, &block_data));
//    ((void (*)(__block_impl *))((__block_impl *)bk)->FuncPtr)((__block_impl *)bk);
    //初始化自定义的block结构体,传入调用方法block_func 传入调用数据block_data

//block调用方法
//1、使用自定义block结构体构造函数,初始化自定义block结构体,并赋值需要block调用的方法
    struct block_method bm((void *)block_func, &block_data);
    void(*bk)(void);//方法指针
//2、从自定义方法中强转出系统block结构体,
    bk = (void (*)(void))&bm;
    __block_impl *p_bk = (__block_impl *)bk;
//3、调用系统结构体定义方法
    ((void (*)(void))p_bk->FuncPtr)();
}

仔细看block 调用方法,这不就是个简单工厂模式,只要block执行,block方法就由系统block结构的FuncPtr来调用,相关调用参数和返回参数靠方法指针强制转换

你可能感兴趣的:(oc block潜入研究)