iOS block分析
block是代码块,其本质和变量类似。不同的是代码块存储的数据是一个函数体。使用Block,就可以像其他标准函数一样,传入参数,并得到返回值。
可以把Block当做Objective-C的匿名函数,Block允许开发者在两个对象之间将任意的语句当做数据进行传递,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息。
Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等。
ARC情况下
1.如果用copy修饰Block,该Block就会存储在堆空间。则会对Block的内部对象进行强引用,导致循环引用。内存无法释放。
解决方法:
新建一个指针(__weak typeof(Target) weakTarget = Target )指向Block代码块里的对象,然后用weakTarget进行操作。就可以解决循环引用问题。
2.如果用weak修饰Block,该Block就会存放在栈空间。不会出现循环引用问题。
MRC情况下
用copy修饰后,如果要在Block内部使用对象,则需要进行(__block typeof(Target) blockTarget = Target )处理。在Block里面用blockTarget进行操作。
默认情况下,Block内部不能修改外面的局部变量。
Block内部可以修改使用__block修饰的局部变量。
1、无参数无返回值的Block
/**
* void :就是无返回值
* emptyBlock:就是该block的名字
* ():这里相当于放参数。由于这里是无参数,所以就什么都不写
*/
void (^emptyBlock)() = ^(){
NSLog(@"无参数,无返回值的Block");
};
emptyBlock();
2、有参数无返回值的Block
/**
* 调用这个block进行两个参数相加
*
* @param int 参数A
* @param int 参数B
*
* @return 无返回值
*/
void (^sumBlock)(int ,int ) = ^(int a,int b){
NSLog(@"%d + %d = %d",a,b,a+b);
};
/**
* 调用这个sumBlock的Block,得到的结果是20
*/
sumBlock(,);
3、有参数有返回值的Block
/**
* 有参数有返回值
*
* @param NSString 字符串1
* @param NSString 字符串2
*
* @return 返回拼接好的字符串3
*/
NSString* (^logBlock)(NSString *,NSString *) = ^(NSString * str1,NSString *str2){
return [NSString stringWithFormat:@"%@%@",str1,str2];
};
//调用logBlock,输出的是 我是Block
NSLog(@"%@", logBlock(@"我是",@"Block"));
Block结合typedef使用
自己定义一个Block类型,用定义的类型去创建Block,更加简单便捷。
/**
* 定义了一个changeColor的Block。这个changeColor必须带一个参数,这个参数的类型必须为id类型的
* 无返回值
* @param id
*/
typedef void(^changeColor)(id);
/**
* 用上面定义的changeColor声明一个Block,声明的这个Block必须遵守声明的要求。
*/
@property (nonatomic, copy) changeColor backgroundColor;
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//声明一个颜色
UIColor *color = [UIColor redColor];
//用刚刚声明的那个Block去回调修改上一界面的背景色
self.backgroundColor(color);
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
ViewController2 *vc =[[ViewController2 alloc]init];
// 回调修改颜色
vc.backgroundColor = ^(UIColor *color){
self.view.backgroundColor = color;
};
[self.navigationController pushViewController:vc animated:YES];
}
iOS-block三种应用场景
- 1.把block保存成对象中的属性,在恰当的时刻调用
2.把block当成方法的参数使用,block的调用在是在方法内部,在外界写block的实现(最常用)
3.把block当成方法的返回值(比较少用)
示例1
1.在Person类中
@interface Person : NSObject
@property (nonatomic,strong) void(^myBlock)(int,int);
@end
2.在ViewController类中
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
int a = ;
int b = ;
Person *p = [[Person alloc] init];
p.myBlock(a,b);
}
示例2
1.在Person类中
@interface Person : NSObject
- (void)eat:(void(^)())block;
@end @implementation Person
- (void)eat:(void (^)())block
{
block();
}
@end
2.在ViewController类中
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 方式1.先定义,在赋值
// void(^block)() = ^() {
// NSLog(@"吃东西");
// };
//
// [p eat:block]; // 方式2.直接写block
[p eat:^{
NSLog(@"吃东西");
}];
}
示例3
1.在Person类中
@interface Person : NSObject
- (void(^)(int))run;
@end @implementation Person
- (void (^)(int))run
{
return ^(int b){
NSLog(@"跑了--%d米",b);
};
}
@end
2.在ViewController类中
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
p.run();
}
iOS block分析的更多相关文章
- iOS block 机制
本文要将block的以下机制,并配合具体代码详细描述: block 与 外部变量 block 的存储域:栈块.堆块.全局块 定义 块与函数类似,只不过是直接定义在另一个函数里,和定义它的那个函数共享同 ...
- iOS Block的本质(四)
iOS Block的本质(四) 上一篇文章iOS Block的本质(三)中已经介绍过block变量的捕获,本文继续探寻block的本质. 1. block内修改变量的值 int main(int ar ...
- # iOS Block的本质(三)
iOS Block的本质(三) 上一篇文章iOS Block的本质(二)中已经介绍过block变量的捕获,本文继续探寻block的本质. 1. block对对象变量的捕获,ARC 环境 block一般 ...
- iOS Block的本质(二)
iOS Block的本质(二) 1. 介绍引入block本质 通过上一篇文章Block的本质(一)已经基本对block的底层结构有了基本的认识,block的底层就是__main_block_impl_ ...
- iOS Block的本质(一)
iOS Block的本质(一) 1.对block有一个基本的认识 block本质上也是一个oc对象,他内部也有一个isa指针.block是封装了函数调用以及函数调用环境的OC对象. 2.探寻block ...
- iOS --------Crash 分析(一)
iOS Crash 分析(文一)- 开始 1. 名词解释 1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID.目的是为了唯一识别这个文件. 2. dwarfdump 苹 ...
- iOS Block界面反向传值
在上篇博客 <iOS Block简介> 中,侧重解析了 iOS Block的概念等,本文将侧重于它们在开发中的应用. Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C ...
- iOS block从零开始
iOS block从零开始 在iOS4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调. block的结构 先来一段简单的代码看看: void ...
- ios Block详细用法
ios Block详细用法 ios4.0系统已开始支持block,在编程过程中,blocks被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行.Blocks可以作为函数参数或者函数的 ...
随机推荐
- 设置虚拟机IP
重启虚拟机 重启后,查看虚拟机IP ip a 虚拟机已有自己的IP 输入虚拟机用户
- __attribute__中constructor和destructor[总结]
1.前言 最近看到一份代码,看到一个函数前面用__attribute__((destructor))修饰,当时感觉有点怪怪的,搜了整个程序,也没发现哪个地方调用这个函数.于是从字面意思猜想,该函数会在 ...
- What is dependency injection and when/why should or shouldn't it be used?
参考:https://stackoverflow.com/questions/130794/what-is-dependency-injection 原文:https://www.jamesshore ...
- Asp.net MVC利用WebUploader上传大文件出现404解决办法。
刚开始我上传小文件都是比较顺利的,但是上传了一个大文件大约有200M的压缩包就不行了.在chrome里面监视发现网络状态是404,我分析可能不是WebUploader的限制,应该是WebConfig限 ...
- EDA: Event-Driven Architecture事件驱动架构
EDA: Event-Driven Architecture事件驱动架构 2009-09-24 17:28 5 赞 异步编程 软件架构 EDA事件驱动 SOA的核心 ...
- SWIFT学习笔记05
1.Swift 无需写break,所以不会发生这样的贯穿(fallthrough)的情况.2.//用不到变量名,可用"_"替换 for _ in 1...power { answe ...
- UiTextField 限制输入长度
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementS ...
- 线程:主线程、子线程 同步线程、异步线程 单线程、多线程 System.Threading与System.Windows.Threading
入门-------------------------------------------------------------------------------- 概述与概念 一个C#程序开始 ...
- linux测试工程介绍(Linux Test Project)
http://ltp.sourceforge.net/ Linux Test Project, 后台很硬,由SGI™ 发起, IBM维护,所以质量有保障. 里面介绍了很多工具,对于一般的基准测试应该是 ...
- 1051: 手机(MOBILE)
#include <iostream> #include <iomanip> #include <cstdlib> #include <string> ...