block的作用: 传值很方便, 但是有一个弊端就是不便于阅读
//
给
block
起别名
typedef
int
(^sumBolck)(
int
,
int
) ;
/*
block 复习 block 是函数 , 而且是匿名函数 , 存在栈区 问题 : 函数与方法的区别 ? 方法 : 方法依托于类和对象 , 有类或对象时才可以调用 函数 : 是利用函数名调用的 , 不依托类 */ // 写一个 block 返回两个数的和 sumBolck sumBk= ^ int ( int x, int y) { return x + y;
};
|
过程:
#import <UIKit/UIKit.h>
// 声明一个无返回值, 无参数的 block, 并起一个别名
typedef void(^myBlock)();
@interface touchView : UIView
//{ // 声明了一个无返回值, 无参数的实例变量
// myBlock _block;
//}
// 声明了一个无返回值, 无参数的block属性, 一定要用copy
@property (nonatomic, copy) myBlock block;
// 声明一个字符串, 是为了与block的set方法进行对比
@property (nonatomic, copy) NSString *str;
@end
- (void)dealloc {
Block_release(_block);
[super dealloc];
}
- (void)setStr:(NSString *)str {
if (_str != str) {
[_str release];
_str = [str copy];
}
}
// block setter方法完整实现
- (void)setBlock:(myBlock)block {
if (_block != block) {
Block_release(_block); // 释放block
_block = Block_copy(block); // 把在栈区的block拷贝到堆区
}
}
调用block
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"触摸动作发生");
// 触摸TouchView改变secondView的背景颜色
// 1. 使用代理实现
// 2. 使用target/action实现
// 3. 用block实现
/*
block方法:
1. 把block写成一个属性
2. 在dealloc中释放掉
3. 触发方法时调用block
4. 找到对象, 实现block
*/
//调用block
self.block();
}
使用block会造成循环引用, 内存无法释放, 所以使用方法解决这个问题
// 采用__block修饰, 可以避免循环引用, 用 myVC 代替self
__block SecondViewController *myVC = self;
// block的实现
touch.block = ^() {
// block中不能出现self有可能会出现循环引用导致内存泄露
NSLog(@"调用了");
// 1. 换背景颜色
myVC.view.backgroundColor = [UIColor orangeColor];
// 2. pop回去
[myVC.navigationController popToRootViewControllerAnimated:YES];
};