您的位置:首页 > 移动开发 > Objective-C

objective-c之block 总结

2016-04-05 22:08 537 查看

一.基本概念

1.Blocks的定义:
int (^MySum)(int, int) = ^(int a, int b) {
return a+b;
};
定义了一个叫MySum的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现
Block可以访问局部变量,但是不能修改。
int sum = 10;
int (^MyBlock)(int) = ^(int num) {
sum++;//编译报错
return num * sum;
};
2.block的赋值:
在声明的同时定义变量,然后赋值
int (^MySum)(int,int) = ^(int a,int b) {
return a + b;
};
也可先用typedef先声明类型,再定义变量进行赋值
typedef int (^MySum)(int,int);
MySum sum = ^(int a,int b) {
return a + b;
};

二.基本使用

/**
定义了一个没有返回值没有参数的block
*/
void test()
{
// 定义简单的block变量
// block跟函数很像: 返回值、参数
void (^logStar)() = ^{
NSLog(@"***************");
NSLog(@"***************");
NSLog(@"***************");
};

logStar();
}
/**
定义了一个没有返回值 但有参数的block
*/
void test2()
{
// 定义block变量, 存储一段代码, 这段代码的功能是能打印任意行数的****
void (^logStarBlock)(int) = ^(int numberOfLines){
for (int i = 0; i<numberOfLines; i++) {
NSLog(@"***************");
}
};
logStarBlock(1);
}
/**
定义了一个有返回值有参数的block
*/
void test3()
{
// 定义一个block计算两个整数的和
int (^sumBlock)(int, int) = ^(int num1, int num2) {
return num1 + num2;
};
int c = sumBlock(10, 9);

// 定义一个block计算一个整数的平方
int (^pinfangBlock)(int);
pinfangBlock = ^(int num){
return num * num;
};

pinfangBlock = ^(int num) {
return num + 2;
};

int d = pinfangBlock(10);
NSLog(@"d is %d", d);
}
Block和typedef
#import <Foundation/Foundation.h>

// 定义一个叫做MyBlock的类型
// 利用MyBlock类型可以定义block变量
// 利用MyBlock类型定义出来的变量, 存储的代码必须返回int, 必须接受2个int类型的参数
typedef int (^MyBlock)(int, int);

int main(int argc, const char * argv[])
{
@autoreleasepool {
MyBlock minusBlock = ^(int num1, int num2) {
return num1 - num2;
};

MyBlock multiBlock = ^(int num1, int num2) {
return num1 * num2;
};

multiBlock(10, 1);

}
return 0;
}

void test()
{
// 定义一个block来计算2个整数的差
int (^minusBlock)(int, int) = ^(int num1, int num2) {
return num1 - num2;
};

// 定义一个block来计算2个整数的积
int (^multiBlock)(int, int) = ^(int num1, int num2) {
return num1 * num2;
};
}
模拟block使用场景
#import <Foundation/Foundation.h>

typedef void (^WorkBlock)();

void goToWork(WorkBlock workBlock)
{
NSLog(@"起床");
NSLog(@"刷牙");
NSLog(@"穿衣服穿鞋");

NSLog(@"出门");
NSLog(@"搭公交");

NSLog(@"抵达公司");

// 实事
// 调用block之前一定要做判断
if (workBlock != nil) {
workBlock();
}
// 实事

NSLog(@"叮咚叮咚 下班了");
NSLog(@"搭公交");
NSLog(@"回家");
NSLog(@"睡觉");
}

/**
模拟星期一上班的具体情况
*/
void goToWorkInDay1()
{
goToWork(^{
NSLog(@"了解项目的需求");
});
}

void goToWorkInDay2()
{
// 实事
goToWork(^{
NSLog(@"熟悉公司以前的代码");
});
// 实事
}

void goToWorkInDay3()
{
// 实事
goToWork(^{
NSLog(@"开始编写代码");
});
// 实事
}

void test(int (^myblock)(int num1, double num2, char num3))
{

}

int main(int argc, const char * argv[])
{
@autoreleasepool {
////        goToWorkInDay3();
//        test(^int(int num1, double num2, char num3) {
//
//        });

//        WorkBlock block = ^{
//            NSLog(@"-------------------");
//        };
//
//        goToWork(block);
}
return 0;
}
场景二:
#import "ViewController.h"

typedef void (^FINISHED)();

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

[self loadData];

[self loadData2:^{
NSLog(@"执行回调");
}];

[self loadData3:@"lnj" finished:^{
NSLog(@"执行回调");
}];
}

- (void)loadData2:(void (^)())finished {
NSLog(@"耗时操作");
finished();
}

- (void)loadData3:(NSString *)name finished:(void (^)())finished
{
NSLog(@"name = %@", name);
finished();
}

- (void)loadData{
dispatch_async(dispatch_get_global_queue(0, 0), ^{

NSLog(@"耗时操作 %@", [NSThread currentThread]);

dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主线程更新UI %@", [NSThread currentThread]);
});
});
}

@end

三.block进阶使用

1.避免block循环引用结合AFNetworking的源码发现有下面几种写法均可:


// AFNetworking的写法
__weak __typeof(&*self)weakSelf = self;// 我之前一直这么写的
__weak __typeof(self) weakSelf = self;
// 或者这么写
__weak XxxViewController *weakSelf = self;
// 或者这么写
__weak id weakSelf = self;

2.block回调
/article/7916601.html3.block链式编程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: