Block

来源:互联网 发布:队列允许在哪一端数据 编辑:程序博客网 时间:2024/06/07 17:47

// 如果block 内部要修改外面的局部变量,必须要在外面的变量前面加一个__block
// __block 加上之后 会告知编译器,在block 内部拷贝一个cnt, 这个cnt 和外面的cnt 值 是保持同步的

// 在OC中block 代码块 可以认为是一个对象
// = 右侧的代码块 可以认为就是一个对象

__block int cnt = 0;
// cnt 默认在block 代码块只能读 如果要修改需要加__block
// 当前类的成员变量(或者全局变量)可以在block内部修改

C函数指针

int add(int a, int b) {    return a+b;}int sub(int a, int b) {    return a - b;}int max(int a, int b) {    return a > b ? a : b;}// pFunction指向的是一个返回值为int, 跟两个int参数的函数// pFunction是一个函数指针,存储的是一个返回值为int, 跟两个int参数的函数的入口地址int calculation(int a, int b, int (*pFunction)(int, int)) {    return pFunction(a, b);    // pFunction传过来的是add, 代表 return add(a, b)    // pFunction传过来的是sub, 代表 return sub(a, b)    // pFunction传过来的是max, 代表 return max(a, b)}

Block示例

定义int 类型

typedef int MyInt;

定义block类型

// 定义block类型// 返回值是void, 跟一个空参数 这样一个 block ‘类型’typedef void (^BlockType1)(void); // typedef int MyInt// 返回值是double, 跟两个double参数 这样一个 block ‘类型’typedef double (^BlockType2)(double, double);// 返回值是NSString, 跟两个NSString参数的block ‘类型’typedef NSString* (^BlockType3)(NSString*, NSString*);
BlockType1 block1 = ^{        NSLog(@"it always make me happy");    };    // block1(); // 调用
[self runBlock2:^double(double a, double b) {        return a + b;    }];
 BlockType1 myBlock1 = ^() {        NSLog(@"Every 沙拉拉拉,Every 哦哦哦哦, So shine");    };/**相当于    void (^myBlock1)(void) = ^(){        NSLog(@"Every 沙拉拉拉,Every 哦哦哦哦, So shine");    };     */
// 求两个整型数的和    int (^sum)(int a, int b) = ^(int m, int n) { // ^int(int m, int n)        return m + n;    };
// block语法    // 定义一个block:    /**     * 返回值 (^block名字)(参数列表) = ^返回值(参数列表) {            实现/block代码块/C函数体       };     */

c函数

/**     * void function() {            printf("测试1");        }        void (*pFunction)(void) = function;        pFunction(); // 调用     */

// 对于c函数指针
// void function() {…} 对应 –> ^void(void) {…}
// pFunction对应 –> myBlock
// 类型:返回值为void, 跟一个void参数这么一个’函数/block 类型’

void (^myBlock)(void) = ^void(void) { // 第二个void是返回值类型,这个东西可以省略,即使返回值不是void, 也可以省略,紧跟着^后面的是返回值类型,它可以省略,如果参数不是void, 不可以省略,因为在block内部可能会用到参数        NSLog(@"测试1\n");    };    myBlock(); // 调用

Block内引用外部变量

// int m = 1;    __block int n = 100;    BlockType1 block1 = ^{        // m += 10; // 错误        // NSLog(@"%d", m);        // 在block内部引用局部变量默认是不可以的,局部变量(方法内的变量/对象)在block内部是只读的,不允许修改,要想修改,必须对这些变量/对象加__block标识,加了__block之后,在block内部就会拷贝一份到堆中,并且与原来的变量/对象保持一致        n += 10; // 在block内部对n进行了修改        _score = 200.0; // 成员变量,是可以修改的    };    // block1(); // 调用,执行

Block copy
// 在OC中block 代码块 可以认为是一个对象
// = 右侧的代码块 可以认为就是一个对象
// block默认内存分配是在栈上,copy的时候在堆中开辟空间

 void (^myBlock)(int a) = ^(int a) {            NSLog(@"a: %d", a);        };void (^myBlock2)(int a) = [myBlock copy];void (^myBlock3)(int a) = Block_copy(myBlock);
0 0
原创粉丝点击