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. Tju_Oj_2790Fireworks Show

    这个题主要在于时间复杂度的计算,N是10的6次方,C是10的2次方,OJ系统可接受的时间是10的7次方(室友说是无数先人测出来了┭┮﹏┭┮),所以如果普通遍历的话肯定会超时.而代码中是跳着走了,相当于 ...

  2. 单调栈(G - Sliding Window POJ - 2823 )

    题目链接:https://cn.vjudge.net/contest/276251#problem/G 题目大意:给你n和m,然后问你对于(m,n)这中间的每一个数,(i-m+1,i)这个区间的最小值 ...

  3. APScheduler API -- apscheduler.triggers.cron

    apscheduler.triggers.cron API Trigger alias for add_job(): cron class apscheduler.triggers.cron.Cron ...

  4. VUE组件相关总结!

    定义使用一个组件 <!doctype html> <html lang="en"> <head> <meta charset=" ...

  5. 关于Unix/Linux的终端、伪终端、控制台和shell

    历史是什么:是过去传到将来的回声,是将来对过去的反映. ——雨果(法)<笑面人> 阅读本文大概需要花费你15分钟 文章导航: 计算机的发展 UNIX系统的诞生 UNIX系统的发展 终端与控 ...

  6. 80.YCrCb - YUV - RGB之间的介绍

    一,引言 YUV(亦称YCrCb)是被欧洲电视系统所采用的一种颜色编码方法(属于PAL).YUV主要用于优化彩色视频信号的传输,使其向后兼容老式黑白电视.与RGB视频信号传输相比,它最大的优点在于只需 ...

  7. weblogic更改端口

    两种方式: 1.访问console控制台页面,进入“环境\服务器\需要修改端口的服务器如AdminServer”,修改监听端口,保存并激活更改即可: 2.修改配置文件,进入weblogic的域目录,如 ...

  8. linux cpu、内存、硬盘空间查询

    [CPU] 算式: CPU总核数 = 物理CPU个数 * 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 * 每颗物理CPU的核数 * 超线程数 #查看CPU型号 cat /proc/cpu ...

  9. 美国部分科技公司创始及IPO信息

    作者:Ben.Z 时间:2018-04-19 做这份统计表格的目的是为了更好地了解当下美国的IT发展,搞清楚那些耳熟能详的名词的来源. 原文是用WPS统计的,本文仅展示截图. 创始人年龄分析: 1.上 ...

  10. align="absmiddle" 的意义

    align=absmiddle表示图像的中间与同一行中最大元素的中间对齐 AbsBottom 图像的下边缘与同一行中最大元素的下边缘对齐. AbsMiddle   图像的中间与同一行中最大元素的中间对 ...