iOS - Block的简单使用
.独立Block
.内联Block
// 定义一个Block Object,返回值:NSString;别名:intToString;参数:NSUInteger。
NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){
NSString *result = [NSString stringWithFormat:@"%lu",(unsignedlong)paramInteger];
return result;
};
// 调用我们定义的Block Ojbect NSString *string = intToString(); NSLog(@"string = %@", string);
typedef NSString* (^IntToStringConverter)(NSUInteger paramInteger);
- (NSString *)convertIntToString:(NSUInteger)paramInteger usingBlockObject:(IntToStringConverter)paramBlockObject{
return paramBlockObject(paramInteger);
}
NSString *result = [self convertIntToString: usingBlockObject:intToString];
NSLog(@"result = %@", result);
typedef NSString* (^IntToStringConverter)(NSUInteger paramInteger);
- (NSString *)convertIntToString:(NSUInteger)paramInteger usingBlockObject:(IntToStringConverter)paramBlockObject{
return paramBlockObject(paramInteger);
}
- (void) doTheConversion{
IntToStringConverter inlineConverter = ^(NSUInteger paramInteger){
NSString *result = [NSString stringWithFormat:@"%lu", (unsignedlong)paramInteger];
return result;
};
NSString *result = [self convertIntToString:123usingBlockObject:inlineConverter];
NSLog(@"result = %@", result);
}
[self doTheConversion];
什么是内联Block?
我的理解是,写在方法内部的,编译器在编译阶段无法知道要调用的具体Block内容。
就像上边的例子:
独立Block:在编译阶段,已经就定义好了Block方法:
// 定义一个Block Object,返回值:NSString;别名:intToString;参数:NSUInteger。
NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){
NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger];
return result;
};
内联Block:在编译阶段,编译器并不知道所关联的Block是什么。
因为它是在调用doTheConversion方法时,临时分配的(inlineConverter)。红色块。
- (void) doTheConversion{
IntToStringConverter inlineConverter = ^(NSUInteger paramInteger){
NSString *result = [NSString stringWithFormat:@"%lu", (unsignedlong)paramInteger];
return result;
};
NSString *result = [self convertIntToString: usingBlockObject:inlineConverter];
NSLog(@"result = %@", result);
}
同理,就相当于:
- (void) doTheConversion{
NSString *result =[self convertIntToString:
usingBlockObject:^(NSUInteger paramInteger) {
NSString *result = [NSStringstringWithFormat:@"%lu",(unsigned long)paramInteger];
return result;
}];
NSLog(@"result = %@", result);
}
是啊,很多iOS中的方法,用的都是这种方式!对用的就是内联Block!!!
原来如此啊!
先mark到这里吧!
下一步,我们来了解一下,关于Block变量的一些东西!
Block 的变量
1.独立Block 变量的操作。
定义Block:
void (^independentBlockObject)(void) = ^(void){
NSInteger localInteger = ;
NSLog(@"local integer = %ld", (long)localInteger);
localInteger = ;
NSLog(@"local integer = %ld", (long)localInteger);
};
调用:
independentBlockObject();
输出:
-- ::50.144 DemoVideo[:] local integer = -- ::50.147 DemoVideo[:] local integer =
2.内联Block 变量的操作。
我们知道Object-C中已经有很多用Block作为参数的函数。该Block参数,作为内联Block调用。
于是,就用一个数组比较的方法:
定义:
- (void) simpleMethod{
NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:@"",@"",@"", nil];
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([obj1 integerValue] < [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
}
调用:
[self simpleMethod];
输出:
Printing description of sortedArray: <__NSArrayI 0x1f56d430>( , , ) Printing description of array: <__NSArrayM 0x1f585ed0>( , , )
我们不用关心,sortedArrayUsingComparator方法的内部实现是什么,但是,它在运行中,调用了内部变量:obj1和obj2
可见:独立Block可以在内部定义变量,访问变量,修改变量!
Block可以读写自己内部的变量,那么对于外部变量,有如何呢 ?
不着急,我们先来归纳一下用于测试的相关代码:
定义Block签名
typedef NSString* (^UserMyBlockFun)(NSUInteger paramInteger);
定义Block为参数的函数
- (NSString *)convertIntToString:(NSUInteger)paramInteger usingBlockObject:(UserMyBlockFun)paramBlockObject{
return paramBlockObject(paramInteger);
}
定义调用函数:
- (void) doTheConversion{
__block int outsideVariable=;
NSString *result =[self convertIntToString:
usingBlockObject:^(NSUInteger paramInteger) {
// 访问self
NSLog(@"self = %@", self);
// 访问self的实体变量
NSLog(@"self = %@", self.strName);
int insideVariable=;
insideVariable+=;
// 输出内部变量,没问题,对内部变量可读写
NSLog(@"insideVariable:%d",insideVariable);
// 输出外部变量,可以读取外部变量,但是不能修改,否则将报出一个错误。
// Variable is not assignable(missing __block type specifier)
NSLog(@"outSideVariable:%d",outsideVariable);
// outsideVariable+=3;
NSLog(@"outSideVariable:%d",outsideVariable);
NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger];
return result;
}];
NSLog(@"result = %@", result);
}
可见,对于外部普通变量,Block只有读取的权限。
但是,从一个错误:Variable is not assignable(missing __block type specifier)中,也许我们可以知道,
如果,要对外部变量具有写权限,那么就要在变量前,加上“__block”
__block int outsideVariable=;
这样,就可以读写outsideVariable变量了。
内联Block可以直接访问self;但是,独立Block不能直接访问self,替代方式为,将self作为参数,传递给Block。
如:
// 独立Block
void (^correctBlockObject)(id) = ^(id self){
// 将self作为参数传递
NSLog(@"self = %@", self);
// 访问self变量
NSLog(@"self = %@", [self strName]);
};
- (void) callCorrectBlockObject{
correctBlockObject(self);
}
有一点非常重要:
内联Block,调用的外部变量,使用的是复制方式。
运行一下,查看输出就知道了:
- (void) scopeTest{
NSUInteger integerValue = ;
// 定义内联Block
BlockWithNoParams myBlock = ^{
NSLog(@"Integer value inside the block = %lu", (unsignedlong)integerValue);
};
integerValue = ;
// 调用Block
myBlock();
NSLog(@"Integer value outside the block = %lu",(unsigned long)integerValue);
}
如果要使用引用方式,那么就要在变量前加上“ __block”
调用 Block
关于内联Block,因为其就是写在方法内的,所以,调用起来相对方便。就像iOS中的API,有很多方法,使用了内联Block方式。
关于独立Block,主要使用C语言的函数调用方式。
用例子来说明吧。
1.调用Block
// 定义Block
void (^simpleBlock)(NSString *) = ^(NSString *theParam){
NSLog(@"the string=%@",theParam);
};
// 调用Block
- (void) callSimpleBlock{
simpleBlock(@"O'Reilly");
}
2.嵌套调用
// 定义内层Block
NSString *(^trimString)(NSString *) = ^(NSString *inputString){
NSString *result = [inputString stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
return result;
};
// 定义外层Block
NSString *(^trimWithOtherBlock)(NSString *) = ^(NSString *inputString){
return trimString(inputString);
};
// 调用方法
- (void) callTrimBlock{
NSString *trimmedString = trimWithOtherBlock(@" O'Reilly ");
NSLog(@"Trimmed string = %@", trimmedString);
}
iOS - Block的简单使用的更多相关文章
- iOS Block的简单使用以及__block 和static修饰变量
简单的代码总结,不足之处多多指教. //简单的使用 -(void)blockOne{ ; int(^BlockOne)(int) = ^(int num2) { return number*num2; ...
- 关于Block的简单使用
Block在整个iOS开发中无所不见,很重要,很重要,文本在这里block的简单使用介绍.我们可以简单地定义.使用block. 1. Block和C的指针函数很像,但比C的函数灵活多了.废话了.... ...
- iOS block从零开始
iOS block从零开始 在iOS4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调. block的结构 先来一段简单的代码看看: void ...
- iOS block并发
多核运算 在iOS中concurrency编程的框架就是GCD(Grand Central Dispatch), GCD的使用非常简单.它把任务分派到不同的queue队列来处理.开发者把任务代码装到一 ...
- iOS Block的本质(一)
iOS Block的本质(一) 1.对block有一个基本的认识 block本质上也是一个oc对象,他内部也有一个isa指针.block是封装了函数调用以及函数调用环境的OC对象. 2.探寻block ...
- iOS Block理解
以前看到Block觉得也没什么,不就是类似函数的东西,这东西在C#里就是委托,在Java里就是块,有什么稀奇的.但看到一点进阶的内容后,发现这个东西确实有用. 所以做下总结. 一.块的基本用法 块的语 ...
- iOS Block界面反向传值
在上篇博客 <iOS Block简介> 中,侧重解析了 iOS Block的概念等,本文将侧重于它们在开发中的应用. Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C ...
- OC block的简单使用
http://blog.csdn.net/itpeng523/article/details/23965147 一.先用Xcode创建一个空工程 学习block之前先用弄懂c语言的函数指针 看代码: ...
- iOS - Block 代码块
1.Block Block 是一段预先准备好的代码,可以在需要的时候执行,可以当作参数传递.Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.Block 是 C 语言的, ...
随机推荐
- BarTender怎么打印公式化的三列标签
有小伙伴在业务上有这样的需求:使用BarTender打印一行三列的标签,如下A,B,C三个并排.第一行 A1=a B1=a*2-1 C1=a*2:第二行 A2=a+1 B2=(a+1)*2-1 C2= ...
- Line云端全自动加好友机器人
一个 LINE 帐号可以加入 5,000 名好友,让这些 5,000 名好友收到 LINE 的主动提醒,好友会看到我的头像.主页照片.姓名与状态消息等,这种行为称为 LINE 的曝光. 如果我们要针对 ...
- Nginx服务器之负载均衡策略
http://www.cnblogs.com/1214804270hacker/p/9325150.html
- kendo-ui下拉树形选择(DropDownTreeView)
摘要: 最近项目中有一个特殊的需求,下拉选择部门,但是部门的层级关系要在下来框中体现出来,如下图 下面我就把实现的过程分享给大家,代码如下: dropdowntreeview.js /* * * Dr ...
- Hash冲突的解决方法
虽然我们不希望发生冲突,但实际上发生冲突的可能性仍是存在的.当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体取值时.冲突就难免会发 生.另外,当关键字的实际取值大于哈希表的长度时,而且表中 ...
- Ognl_JSTL_学习笔记
控制标签 使用Struts2标签必须先导入标签库,在页面使用如下代码导入Struts2标签:<%@taglib prefix="s" uri="/struts-ta ...
- php大数除法保留精度问题
有人在群里问大数除法,要求保留精度的问题,发现普通的方法都不能保存精度,最后找了一下资料发现可以这样 这倒是个冷门知识,嗯哼
- linux-nohup后台运行
先说一下linux重定向: 0.1和2分别表示标准输入.标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出. 在一般使用时,默认的是标准输出,既1.当我们需要特殊用途时,可以使用其他标 ...
- 【代码审计】iZhanCMS_v2.1 代码执行漏洞分析
0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...
- 【代码审计】CLTPHP_v5.5.3 前台任意文件上传漏洞分析
0x00 环境准备 CLTPHP官网:http://www.cltphp.com 网站源码版本:CLTPHP内容管理系统5.5.3版本 程序源码下载:https://gitee.com/chich ...