Block
一、概念
BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码。用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行。
BOLCK和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样。
二、定义
block变量的定义:
返回值 函数名 (参数,参数)
返回值 (^block名)(参数)
block定义之后,只有当调用这个block的时候才会返回来执行具体的代码块
例如:
void (^test)(void) = ^{
//具体执行某件事情的代码块
for (int i = 0; i < 5; i++) {
NSLog(@"-----%d" , i+1);
}
};
NSLog(@"*****");
test();
int (^add)(int, int) = ^(int a, int b){
return a + b;
};
int result = add(1, 2);
三、block中的内存管理
1.创建一个block实际上就是分配一片独立的内存空间,去运行block里面的代码块,这个代码块的内存空间已经脱离定义的那个位置了,但是block会保存定义的那个上下文(运行环境)换句话说就是copy了一份上下文,所以在block里面可以访问外部的变量,但是无法改变外部变量的值,如果非要访访问,可以通过在变量前添加一个__block
2. block容易形成循环引用
当在block里面调用某一个类的属性或者方法,用self.name [self test], block会对这个对象进行强引用
__weak typeof(self) weakSelf = self;强制转换为弱引用,防止循环引用
3.block变量用copy修饰
例如:
main.m
__block int a = 10;
Person *jz = [Person new];
void (^change)(int) = ^(int temp){
a++;
jz.name = @"jack";
NSLog(@"a = %d", a);
};
change(a);
NSLog(@"%@", jz.name);
Person.h
@property (nonatomic, strong) NSString *name;
四、使用block做回调
1.先定义好block 然后再去使用
void (^dddd)(int) = ^(int a){
NSLog(@"回调过来 %d", a);
};
Person *p = [Person new];
[p test:dddd];
2.在调用方法的同时去定义这个block
[p test:^(int count) {
NSLog(@"回调过来 %d", count);
}];
Person.h
@interface Person : NSObject
//对block进行类型重定义 为了更好的阅读
typedef void (^CallBack)(int count);
@property (nonatomic, strong) NSString *name;
- (void)test:(CallBack)block;
@end
Person.m
#import "Person.h"
@implementation Person
- (void)test:(CallBack)block{
//回调数据
block(10);
}
@end
3.block做回调例子:delegates例子用block实现
Agent.h
#import <Foundation/Foundation.h>
typedef void(^CompleteBlock)(NSString *name);
@interface Agent : NSObject
- (void)rentHouse:(CompleteBlock)block;
@end
Agent.m
#import "Agent.h"
@implementation Agent
-(void)rentHouse:(CompleteBlock)block{
block(@"Jack");
}
@end
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)needHouse;
@end
Person.m
#import "Person.h"
#import "Agent.h"
@implementation Person
- (void)needHouse{
Agent *xw = [Agent new];
[xw rentHouse:^(NSString *name) {
NSLog(@"你好%@", name);
}];
}
@end