NSString* (^myBlock)(NSString*, int);

myBlock = ^(NSString *name, int age){
return [NSString stringWithFormat:@"My name is %@,I‘m %d years old!",name,age];
}; NSString *str = myBlock(@"胡晓伟",);
NSLog(@"%@",str);

上面的例子演示了Block的基本用法,Block声明的基本结构是:

返回类型 (^变量名)(参数列表..)

例如:

void (^myBlock1)(void);  //无返回值,无参数
void (^myBlock2)(NSObject, int); //有返回值,有参数
NSString* (^myBlock3)(NSString* name, int age); //有返回值和参数,并且在参数类型后面加入了参数名(仅为可读性)

将一个Block定义为函数参数:

- (void)testBlock:(NSString *(^)(void)) myName
{
NSLog(@"My Name is %@",myName());
} - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *(^myBlock)(void) = ^{ return @"wayne"; }; [self testBlock:myBlock]; return YES;
}

下面看看如何通过Block访问不同上下文环境的局部变量:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *str = @"AAA"; NSString *(^myBlock)(void) = ^(void){
return str;
}; [self logBlock:myBlock]; return YES;
} - (void)logBlock:(NSString *(^)(void))block
{
NSLog(@"%@",block());
}

下面的代码测试了可变对象与不可变对象在Block中的情况:

NSString *str1 = @"str1";
NSMutableString *str2 = [NSMutableString stringWithString:@"str2"]; NSLog(@"************初始值与初始地址************");
NSLog(@"【%@】,【%p】",str1,&str1);
NSLog(@"【%@】,【%p】",str2,&str2); void (^myBlock)(void) = ^{
NSLog(@"************Block中输出************");
NSLog(@"【%@】,【%p】",str1,&str1);
NSLog(@"【%@】,【%p】",str2,&str2);
}; str1 = @"str1_update";
[str2 appendString:@"_update"];
NSLog(@"************更新后的值与地址************");
NSLog(@"【%@】,【%p】",str1,&str1);
NSLog(@"【%@】,【%p】",str2,&str2); myBlock(); NSLog(@"************调用Block后的值与地址************");
NSLog(@"【%@】,【%p】",str1,&str1);
NSLog(@"【%@】,【%p】",str2,&str2);

输出结果:

************初始值与初始地址************

【str1】,【0xbff4d1f8】

【str2】,【0xbff4d1f4】

************更新后的值与地址************

【str1_update】,【0xbff4d1f8】

【str2_update】,【0xbff4d1f4】

************Block中输出************

【str1】,【0xbff4d1e4】

【str2_update】,【0xbff4d1e8】

************调用Block后的值与地址************

【str1_update】,【0xbff4d1f8】

【str2_update】,【0xbff4d1f4】

可以看出在Block内,不可变对象的值任然是初始化时的值,可变对象的值变成了新值。这是因为Block初始化在前,可变对象的修改在后;如果颠倒顺序,先修改可变对象的值,再初始化Block,这样Block就能同步修改后的值了。

最后看看Block对变量的访问权限:

#import "AppDelegate.h"

@interface AppDelegate ()
{
NSString *str1;
}
@end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *str2 = @"str2"; __block NSString *str3 = @"str3"; void (^myBlock)(void) = ^{ str1 = @"newString"; //ok //str2 = @"newString"; //error str3 = @"newString"; //ok NSLog(@"%@,%@,%@",str1,str2,str3);
}; myBlock(); return YES;
}

在Block里不能直接修改局部变量的值,如果要修改,需要在局部变量前加上修饰关键字__block。

从上面的例子可以看到在Block里能访问并修改类变量、带__block关键字的变量;但是不能修改不带__block关键字的局部变量。

Block的基本用法的更多相关文章

  1. Block 的基本用法

    iOS中Block的基础用法 转载自简书 本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对 ...

  2. iOS中Block的基础用法

    本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...

  3. [HMLY]10.iOS中block的基础用法

    本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...

  4. block的常见用法

    一.声明和定义 1.声明 声明方式:返回值(^block)(参数).声明时,参数变量名可以省略:使用时,参数变量名不能省略,不然会无法调用传入的参数 void(^block)(); void(^blo ...

  5. Objective-C中Block的常见用法

    typedef int(^AddValue)(int,int); int main(int argc, const char * argv[]) { @autoreleasepool { //1:NS ...

  6. iOS中Block的用法,举例,解析与底层原理(这可能是最详细的Block解析)

    1. 前言 Block:带有自动变量(局部变量)的匿名函数.它是C语言的扩充功能.之所以是拓展,是因为C语言不允许存在这样匿名函数. 1.1 匿名函数 匿名函数是指不带函数名称函数.C语言中,函数是怎 ...

  7. block 从B界面向A界面传值

    最近在改公司外包项目的代码,发现了一种block传值的用法很有意思,记录一下 A.B两个页面 在B界面.h中定义 @property (nonatomic,strong) void(^block)(N ...

  8. 关于block的一些理解

    之前一直都是用这别人或者是系统系统封装好的block,用这都挺好,可以访问那些定义了block变量的函数变量在block中使用. 首先总结一个block的用法:1.block有些类似于函数的指针 拥有 ...

  9. OC之Block的用法和实现委托

    Block的基本概念 Block的基本用法 Block实现委托机制 一.Block的基本概念 Block是程序的代码块,这个代码块可以在需要的时候执行.IOS开发中,block到处可见,所以学好很重要 ...

随机推荐

  1. Python文件操作-文件的增删改查

    需求:对文件进行增删改查 由于时间原因,本次代码没有增加任何注释,如有疑问,请联系编辑者:闫龙 其实我也是醉了,看着这些个代码,我脑袋也特么大了,没办法,大神说了,不让用新知识,只可以使用学过的,所以 ...

  2. 添加 MySql 服务、Tomcat服务到windows服务中

    添加 MySql 服务到windows服务中: cmd --> F:\MySql\MySqlServer5.1\bin\mysqld --install 这样用默认的 MySQL 为名称添加一个 ...

  3. VUE常用指令总结!

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Solr管理索引库——(十三)

    a)          维护索引 1.  添加/更新文档 添加或更新单个文档

  5. sqlite3 的insert记录项思路

    sqlite3 的insert记录项思路 1.组合一个insert的sql语句 2.判断是否需要立即执行,若不是立刻执行的语句,则插入到待处理的链表中,供后续事务处理时提交.必须有一个专门线程来对事务 ...

  6. Codeforces Round #504 E. Down or Right

    Codeforces Round #504 E. Down or Right 题目描述:交互题. 有一个\(n \times n\)的方阵,有一些格子是障碍,从\((1, 1)\)出发,只能向右向下走 ...

  7. Python [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 解决方法

    一个搭建在SAE上的Django应用,使用新浪微博提供的Python SDK已经稳定运行一年有余,但最近开始持续出现微博认证失败的状况. 摘录微博python SDK的错误提示如下所示: ERROR: ...

  8. log4j与commons-logging slf4j的关系

    1. slf4j     他只提供一个核心slf4j api(就是slf4j-api.jar包),这个包只有日志的接口并没有实现     所以如果要使用就得再给它提供一个实现了些接口的日志包,     ...

  9. 网络协议之UDP

    前言 TCP协议在不可靠的网络环境上提供了可靠的通信通道,隐藏了大量的底层细节,使应用程序更加简洁.但有些应用并不需要这么高的可靠性,并不需要按序交付,而且TCP为了提高可靠性也增加了延时,在某些对延 ...

  10. 用django-cors-headers做跨域

    什么是CORS? CORS(跨域资源共享,Cross-Origin Resource Sharing)是一种跨域访问的机制,可以让Ajax实现跨域访问. 其实,在服务器的response header ...