每每也是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節
嵌套層次太深不要使用 -> 不利於代碼調用、直觀性較差。