每每也是1.2用法中,函数接收方中的用法。java
AFN中response的代码写在block中,能够把业务逻辑写在一块儿。objective-c
响应式编程
,AFN中,发送请求具体实现是AFN作的,何时返回也不肯定。 这里用通知、delegate都会比block复杂。sql
oc中链式的本质
:编程
()
是执行block,至关于调用了一个函数。//Human.h
- (Human *(^)(int))run;
//Human.m
- (Human *(^)(int))run {
return ^Human *(int m) {
NSLog(@"%d", m);
return self;
};
}
//invoke somewhere
Human *human = [Human new];
Human *(^block)(int) = human.run;
block(10);
//合起来
human.run(10);
复制代码
所谓捕获,就是指,把栈上变量的值
copy到堆上。bash
局部变量create在堆上
,block捕获时直接强引用。
=赋值
,会执行一个copy操做,变成了堆上的blockARC下写copy仍是strong,都会copy,但最好仍是写copy提醒本身和别人。网络
//全局block
NSLog(@"globalBlock2, %@", ^{
NSLog(@"globalBlock");
});
//栈block, 使用了外部变量 -> 栈block
int i = 2;
NSLog(@"stackBlcok, %@", ^{
NSLog(@"stackBlcok, %d", i);
});
//堆block, 栈block,进行了赋值操做 -> 堆block
void (^heapBlock) (void) = ^{
NSLog(@"heapBlock, %d", i);
};
NSLog(@"heapBlock, %@", heapBlock);
heapBlock();
复制代码
//对于已经在堆上的block,赋值操做不会再进行copy,[block copy]后,仍然是原地址
//也就是说,block的copy已经很是的自动化,显示的写 [block copy],已经彻底没必要要了
void (^heapBlock) (void) = ^{
NSLog(@"heapBlock, %d", i);
};
NSLog(@"heapBlock, %@", heapBlock);
heapBlock();
self.globalBlock = heapBlock;
NSLog(@"self.globalBlock, %@", self.globalBlock);
self.globalBlock = [heapBlock copy];
NSLog(@"self.globalBlock, %@", self.globalBlock);
复制代码
三种方式中,保持一致的地方:入参的格式,返回类型都不带括号。 语法比较丑,多写几回才能练到手熟,也能够用下面的快捷方式。session
//Xcode中,输入inline,会有提示的block定义出来
复制代码
//1. 返回类型不带括号
//2. block名、参数集带括号
//3. 参数集相似Java
typedef void (^TrueFalseCallback)(BOOL success);
typedef NSString * _Nonnull (^ABlock)(UIImage * _Nullable image);
复制代码
@property (nonatomic, copy) void (^block)(void);
复制代码
//1. 形似typed声明的总体,放在一个括号内,做为类型
//2. block名右移做为形参
//FMDatabaseQueue.m
- (void)inDatabase:(void (^)(FMDatabase *db))block {
//block是参数,这里是函数体,不是block的定义。
FMDatabase *db = [self database];
block(db);
//...
}
复制代码
^返回类型(java形式的入参){block代码块}
/**
RAC中的一个定义
1. 参数是一个 返回值为RACSignal,参数为id的block
2. block内容没有,直接返回了一个RACSignal
3. RACSignal的参数是一个 返回值为RACDisposable,参数为id<RACSubscriber>的block
4. 这个block 是返回了一个nil
*/
[[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[self shuwen:input subscriber:subscriber];
return nil;
}];
}];
复制代码
5-1中,有两个定义的实例框架
简单说,异步
函数调用中,不要把,做为实参的block
的block体,和本次函数调用,搞混了。async
block是传过去的,对方想何时调用,就何时调用,调用的时候,他会按照block的参数设定
去传值.
大多数状况下,能够经过函数名,看出来,对方大概会在何时调用
这个block。
先看这个
//入参中的db,由databaseQueue提供
[[HHBaseSharedDBPersistence databaseQueue] inDatabase:^(FMDatabase *db) {
FMResultSet *resultSet = [db executeQuery:self.sqlString];
if ([resultSet next]) {
dbVersion = [resultSet intForColumn:TABLE_NAME_META_COLUMN];
}
[resultSet close];
}];
复制代码
再看看网络调用中:
AFURLSessionManager *session = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request
progress:^(NSProgress * _Nonnull downloadProgress) {
if (progress) {
dispatch_async(dispatch_get_main_queue(), ^{
progress(downloadProgress.fractionCompleted);
});
}
}
destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {}
completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {}
];
复制代码
最后看Masonry中的使用,对照与1.3节中提到的链式编程。
- (MASConstraint * (^)(id))mas_equalTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
};
}
复制代码
www.jianshu.com/p/ce1f1ee52…的3.4节
嵌套层次太深不要使用 -> 不利于代码调用、直观性较差。