Table of Content
block
定义
inlineBlock
return_value ^(block_name)(arg_list) = return_value ^(arg_list){
code_block;
}
typedef Block
- block是一种数据类型,可以定义类型,当作返回值
typedefBlock.m
#import <Foundation/Foundation.h>
typedef void^(myBlock)();
myBlock myDemo(){
myBlock mb = ^{
NSLog(@"test");
}
return mb;
}
int main(){
myBlock mb = myDemo();
mb();
return 0;
}
循环引用问题
-
block在定义时会默认对外部变量做一次
copy
(强引用) -
在Obj-C中定义指针变量默认都是
strong
类型,可以使用__weak
修饰改为弱引用 -
如果block中出现
self
时要加以注意,可能会出现循环引用(并非绝对) -
利用
dealloc
方法可以协助检测循环引用
调用
block_name(arg_list)
自定义视图传值:block与代理
实现
-
block
-
调用方
- 准备块代码
-
被调用方
-
定义代码块属性
-
需要时执行
-
-
-
代理
-
代理
-
遵守协议
-
设置代理
-
实现方法
-
-
委托
-
定义协议
-
定义代理属性
-
需要时调用代理方法
-
-
block与代理的选择
-
block与代理在一些场合时可以互换的
-
block
-
block适合比较小巧的回调,通常1~3回调方法比较合适
-
如果回调的方法很多时使用block会显得很臃肿,例如UITableView
-
-
代理
- 使用代理可以制定协议方法是否必须实现
-
block数组排序/遍历
compare方法
- 可以比较两个对象 (NSNumber, NSString, NSDate....)
compare
- (NSComparisonResult)compare:(NSNumber *)otherNumber;
数组排序
sortedArrayUsingComparator
- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0);
typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};
/*
NSOrderedAscending = -1L, 升序
NSOrderedSame, 相同
NSOrderedDescending 降序
*/
#if NS_BLOCKS_AVAILABLE
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
#endif
数组遍历
-
所有的参数都已经准备到位,可以直接使用
-
效率比传统方式快(对比
for ( in ){}
)
enumerate
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
示例代码
array_block.m
#import <Foundation/Foundation.h>
int main(){
NSArray* array = @[ @5, @4, @2, @1, @3 ];
// 数组排序
NSArray* result = [array sortedArrayUsingComparator:^NSComparisonResult(NSNumber* num1, NSNumber* num2) {
// 升序
return [num1 compare:num2];
}];
NSLog(@"%@", result);
}
// 数组遍历
void enumerate(NSArray *array){
[array enumerateObjectsUsingBlock:^(NSNumber* num, NSUInteger idx, BOOL* stop) {
NSLog(@"%@", num);
if (idx == 3) { // 遍历到第三个时结束
*stop = YES;
}
}];
}
block常见题目
block-copy
block_copy_release.m
#import <Foundation/Foundation.h>
typedef void^(myBlock)();
myBlock myDemo(){
int i = 10;
myBlock mb = ^{
NSLog(@"i = %d",i);
}
//错误解决办法:⏎ [mb copy];
return Block_copy(mb);
}
int main(){
myBlock mb = myDemo();
mb();
Block_release(mb);
return 0;
}
重构
-
新建方法
-
将代码复制到新方法
-
调整参数
#import <Foundation/Foundation.h>
void myDay(void (^myWork)()) // 和 inlineBock 的左边一模一样
{
NSLog(@"起床");
NSLog(@"出门");
// 执行block参数,在需要的时候执行
myWork();
NSLog(@"下班回家");
NSLog(@"洗洗睡了");
}
void day1()
{
// 准备代码,格式和inlineBlock右边一模一样
myDay(^{
NSLog(@"新人报道");
});
}
void day2()
{
myDay(^{
NSLog(@"看公司代码");
});
}
int main(){
day1();
day2();
return 0;
}