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 语言的, ...
随机推荐
- vue给input file绑定函数获取当前上传的对象
HTML <input type="file" @change="tirggerFile($event)"> JS(vue-methods) tir ...
- Java 11正式发布,这几个逆天新特性教你写出更牛逼的代码
就在前段时间,Oracle 官方宣布 Java 11 (18.9 LTS) 正式发布,可在生产环境中使用! 这无疑对我们来说是一大好的消息.作为一名java开发者来说,虽然又要去学习和了解java11 ...
- 多页Excel转换成PDF时如何保存为单独文件
通过ABBYY PDF Transformer+图文识别软件,使用PDF-XChange打印机将多页Excel工作簿转换成PDF文档(相关文章请参考ABBYY PDF Transformer+从MS ...
- 安装MySQL后经常弹出taskeng.exe~
taskeng.exe,是Microsoft任务计划程序引擎调用的安全进程.文件路径为C:\Windows\system32\taskeng.exe.大小165KB. 解决办法: 这个问题是Wind ...
- 申请LINE 帐号的所有方法
如果你打算用LINE 交朋友或是做行销,你就必须先要拥有一个甚至许多个LINE 帐号.在本篇文章中,将分享给你目前申请LINE 帐号的所有可能方法. 目前LINE 公司允许大家使用以下二种身分申请LI ...
- iphone弹出窗口效果的制作(Core animation, CALayer)
效果类似人人网微薄客户端的弹出效果 static CGFloat kTransitionDuration = 0.3; - (void)initView { UIWindow *window = [U ...
- iOS去掉icon的(自带磨光效果)gloss effects
只需两步,第一步:在项目的plist文件,最上层add row ,内容 icon already includes gloss effects YES. 第二步在 icon files 字段里添加 ...
- 扩展方法(DateTableToList)
public static IList<T> ToList<T>(this DataTable dt) where T : class,new() { var prlist = ...
- IDEA maven项目下测试mybatis例子,使用mappper class或package引入mapper映射文件,总是报错Invalid bound statement(所有配置完全正确)
困扰几个小时,终于查到解决办法及原因(可以直接到最后看解决方案) 环境就是用IDEA搭建的maven项目,主要jar包引入配置如下 <dependencies> <dependenc ...
- 转载linux性能调优工具
Linux 大牛,Netflix 高级性能架构师 Brendan Gregg 更新 Linux 性能调优工具,各种资源应有尽有,大量干货,强烈建议收藏.