iOS 面试全方位剖析 -- Block篇
1.Block的本意
block本质上也是一个OC对象,它内部也有个isa指针,
block是封装了函数调用以及函数调用环境的OC对象,
block是封装函数及其上下文的OC对象

2.block截获变量
#import "SYDBlcok.h"
// 全局变量----不截获全局变量
int global_var = 4;
// 静态全局变量-----不截获全局静态变量
static int static_global_var = 5; @implementation SYDBlcok
-(void)method {
// 基本数据类型的局部变量----只截获值
int var = 6;
// 对象类型的局部变量----连同所有修饰符一起截获
__unsafe_unretained id unsafe_ibject = nil;
__strong id strong_obj = nil;
// 局部静态变量---以指针形式截获局部静态变量
static int multiplier_static = 3;
NSLog(@"multiplier_static:%d",multiplier_static);
int(^Block)(int) = ^(int num) {
NSLog(@"局部变量>基本数据类型:%d",var);
NSLog(@"局部变量>对象类型%@----strong:%@",unsafe_ibject,strong_obj);
NSLog(@"局部static:%d",multiplier_static);
NSLog(@"全局变量%d",global_var);
NSLog(@"静态全局变量:%d",static_global_var);
return num * multiplier_static;
};
NSLog(@"判断执行顺序");
// 局部静态变量 -----isa指针
multiplier_static = 4;
NSLog(@"result is %d",Block(2));
}
编译后结果
2019-04-16 14:59:38.854104+0800 auditionTest[64047:1220987] viewDidLoad
2019-04-16 14:59:42.067785+0800 auditionTest[64047:1220987] multiplier_static:3
2019-04-16 14:59:42.067970+0800 auditionTest[64047:1220987] 判断执行顺序
2019-04-16 14:59:42.068081+0800 auditionTest[64047:1220987] 局部变量>基本数据类型:6
2019-04-16 14:59:42.068182+0800 auditionTest[64047:1220987] 局部变量>对象类型(null)----strong:(null)
2019-04-16 14:59:42.068276+0800 auditionTest[64047:1220987] 局部static:4
2019-04-16 14:59:42.068366+0800 auditionTest[64047:1220987] 全局变量4
2019-04-16 14:59:42.068459+0800 auditionTest[64047:1220987] 静态全局变量:5
2019-04-16 14:59:42.068563+0800 auditionTest[64047:1220987] result is 8
cpp文件解析

- FuncPtr:指向调用函数的地址
- __main_block_desc_0 :block描述信息
- Block_size:block的大小
3. block修饰符
/**
修饰符的使用----对被截获变量进行赋值操作的时候
*/
-(void)block_property {
__block NSMutableArray *array = nil;
// static、static global或者global变量 不需要添加__block
void(^block)(void) = ^{
// 使用array 初始化
array = [NSMutableArray array];
[array addObject:@""];
};
block();
NSLog(@"array:%@",array);
}
// 赋值操作不需要修饰符
-(void)block_property {
NSMutableArray *array = [NSMutableArray array];
// static、static global或者global变量 不需要添加__block void(^block)(void) = ^{ // 使用array 初始化
array = [array addObject:@"123"];
};
block();
NSLog(@"array:%@",array);
}
4.循环引用
// 循环引用
-(void)aroundBlock { _array = [NSMutableArray arrayWithObject:@"block"];
// __weak NSArray *weakArray = _array;
// kWeakSelf(_array);
NSString*(^strBlock)(NSString *str) = ^(NSString *num) {
return [NSString stringWithFormat:@"hello_%@",_array[]];
// return [NSString stringWithFormat:@"hello_%@",weak_array[0]];
};
// self z持有block, block有成员变量 array,持有self
strBlock(@"eden");
} -(void)aroundBlock { _array = [NSMutableArray arrayWithObject:@"block"];
// __weak NSArray *weakArray = _array;
kWeakSelf(_array);
NSString*(^strBlock)(NSString *str) = ^(NSString *num) {
// return [NSString stringWithFormat:@"hello_%@",_array[0]];
return [NSString stringWithFormat:@"hello_%@",weak_array[]];
};
// self z持有block, block有成员变量 array,持有self
strBlock(@"eden");
}
// weakself 配合strongSelf 使用,防止在block执行的时候self提前突然被释放,也有可能闪退
__weak __typeof__(self) weakself = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
__strong __typeof(self) strongself = weakself;
[strongself doSomething];
[strongself doOtherthing];
});
}
-(void)doSomething {
NSLog(@"doSomething");
}
-(void)doOtherthing{
NSLog(@"doOtherthing");
}
使用retain也可以,但是block的retain行为默认是用copy的行为实现的,因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
iOS 面试全方位剖析 -- Block篇的更多相关文章
- 新浪微博资深大牛全方位剖析 iOS 高级面试
第1章 课程简介本章对这门课程所讲述内容进行概要介绍,其中包括课程目标.适合人群,课程特色.课程收获.课程安排等.整个课程学习完结后,有机会获得电话模拟面试及内推. 1-1 课前必读(不看会错过一个亿 ...
- iOS面试贴士
iOS面试小贴士 ———————————————回答好下面的足够了------------------------------------- 多线程.特别是NSOperation 和 GCD 的内部原 ...
- iOS 面试基础题目
转载: iOS 面试基础题目 题目来自博客:面试百度的记录,有些问题我能回答一下,不能回答的或有更好的回答我放个相关链接供参考. 1面 Objective C runtime library:Obje ...
- web前端面试试题总结---css篇
CSS 介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的? (1)有两种, IE 盒子模型.W3C 盒子模型: (2)盒模型: 内容(content).填充(padding).边界(m ...
- 一些iOS面试基础题总结
一些iOS面试基础题总结 目录 多线程 AutoLayout objc_msgSend Runtime 消息转发 Category NSObject 与 objc_class Runloop Auto ...
- iOS 面试秘籍全套
栏目将持续更新--请iOS的小伙伴关注! (答案不唯一,仅供参考,文章最后有福利) iOS面试题大全(上) iOS面试题大全(下) 目录: iOS面试题:Run Loop iOS面试题:性能优化 ...
- web前端面试试题总结---html篇
HTML Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于 <html> 标签之前.告知浏览器的解析器 ...
- iOS push全方位解析(二)【译文】"——生成OpenSSL证书,Provisioning Profile
这是一篇来自raywenderlich的教程,内容翔实!结构简单透彻.讲解循序渐进.文章质量上乘!是一篇难的的博文!使用半瓶的英语水平翻译了一下: 1.[iOS push全方位解析](一) push的 ...
- IOS面试攻略
IOS面试攻略(1.0) 2013-10-13 20:58:09| 分类: IOS面试 | 标签:ios知识点总汇 ios面试 |举报|字号 订阅 来自:伊甸网 @ 看到这个关键字,我 ...
随机推荐
- linux 下载rpm包到本地,createrepo:创建本地YUM源
如何下载rpm包到本地 设置yum安装时,保留rpm包. 1.编辑 /etc/yum.conf 将keepcache的值设置为1; 这样就可以将yum安装时的rpm包保存在 /var/cache/yu ...
- idea集成spring+spring MVC+mybatis问题
1.如果mybatis的xml文件放在java文件夹下(idea不会编译src的java目录的xml文件),需要在pom.xml中加入以下代码: <build> <resources ...
- uva 111 History Grading(lcs)
题目描述 在信息科学中有一些是关于在某些条件限制下,找出一些计算的最大值. 以历史考试来说好了,学生被要求对一些历史事件根据其发生的年代顺序来排列.所有事件顺序都正确的学生无疑的可以得满分.但是那些没 ...
- Using SMOTEBoost(过采样) and RUSBoost(使用聚类+集成学习) to deal with class imbalance
Using SMOTEBoost and RUSBoost to deal with class imbalance from:https://aitopics.org/doc/news:1B9F7A ...
- Tomcat报错:HTTP Status 500 - Wrapper cannot find servlet class
HTTP Status 500 - Wrapper cannot find servlet class com.servlet.servlet.RegServlet or a class it dep ...
- poj-1442 Black Box(Treap)
题目链接: Black Box 题意: 给一个序列,m个询问,每个询问是求前x个数中的第i小是多少; 思路: Treap的入门题目;Treap能实现STL的set实现不了的功能,如名次树(rank t ...
- rtmp与hls流媒体服务器搭建:ubuntu下Nginx搭建初探与rtmp-module的添加
关键词:Nignx(http服务器):rtmp,hls(流媒体服务) 前言:感谢开源,感谢战斗民族.现在在做流媒体服务的一些工作,流媒体服务器搭建的网上教程多入牛毛,但是细细查看,发现很多同志贴上来的 ...
- ACM学习历程—ZOJ3785 What day is that day?(数论)
Description It's Saturday today, what day is it after 11 + 22 + 33 + ... + NN days? Input There are ...
- bzoj 2631: tree link-cut-tree
题目: Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u ...
- CodeForces - 605C 凸包+直线与凸包判交
题目大意: 要完成两种属性p,q的需求,给定n个双属性物品及其单位个物品中含有的属性,要求选择最少的物品来达成属性需求.(可以选择实数个物品) 题解: 实际上是一种属性混合问题 我们知道对于两种双属性 ...