Block的使用

Block:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

//  main.m

//  块的使用

 

#import <Foundation/Foundation.h>

#include <stdlib.h>

 

typedef void (^DownloadURL)(void);

 

//获取用于下载URL的块

DownloadURL getDownloadURLBlock(NSString *url)

{

    NSString *urlString = url;

    return ^{

        //下载URL

        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];

        NSError *error;

        NSDate *startTime = [NSDate date];

        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];

        if (data == nil) {

            NSLog(@"Error loading request %@", [error localizedDescription]);

        }

        else {

            NSDate *endTime = [NSDate date];

            NSTimeInterval timeInterval = [endTime timeIntervalSinceDate:startTime];

            NSLog(@"Time taken to download %@ = %f seconds", urlString, timeInterval);

        }

    };

}

 

int main(int argc, const char * argv[]) {

    @autoreleasepool {

        //block可以理解为闭包或者lambda也可以是函数指针 也可以是匿名内部类

         

#pragma mark - 块的定义

        /*定义块的语法格式如下:

            ^[块返回值类型] (形参类型1 形参1,形参类型2 形参2,  ...){

            //块执行体

            }

        */

        //定义不带参数、无返回值的块

        void (^printStr) (void) = ^(void){

            NSLog(@"这是块");

        };

        //使用printStr调用块

        printStr();

         

        //定义带参数、有返回值的块

        double (^hypot) (double ,double) = ^(double num1 ,double num2){

            return sqrt(num1 * num1 + num2 * num2);

        };

        //调用块,并输出块的返回值

        NSLog(@"%g" , hypot(3,4));

         

        //也可以先只定义块变量:定义带参数、无返回值的快

        void (^print) (NSString *);

        //再将块赋值给指定的块变量

        print = ^(NSString * info){

            NSLog(@"info参数为:%@" , info);

        };

        //调用块

        print(@"测试块调用");

         

#pragma mark - 修改局部变量的值

        /*块可以访问程序中局部变量的值,当块访问局部变量的值时,不允许修改局部变量的值

         如果不希望在定义块时就把局部变量的值复制到块中,而是等到执行时才去访问、获取局部变量的值,

         甚至希望块也可以改变局部变量的值,此时可以考虑使用__block修饰局部变量。*/

        //定义__block修饰的全局变量

        //int one = 1;

        __block int my = 20;

        void (^printMy)(void) = ^(void){

            //运行时访问、获取局部变量的值,此处输出45

            NSLog(@"%d" , my);

            //尝试对_block局部变量赋值是允许的

            my = 30;

            //one = 2;      //Xcode会提示无法对one进行修改,除非用__block进行了修饰

            //此处输出30

            NSLog(@"%d" , my);

        };

        my = 45;

        printMy();//调用块

        //由于块修改了__block局部变量的值,因此下面的代码输出30

        NSLog(@"块执行完后,my的值为:%d" , my);

         

#pragma mark - 使用typedef定义块类型

        /*使用typedef定义块类型的语法格式如下:

            typedef 块返回值类型 (^块类型) (形参类型1 [形参名] ,形参类型2 [形参名] , ... );

        */

        /*使用typedef可以定义块类型,定义了块类型后,该块类型主要有如下两个用途:

            1.复用块类型,使用块类型可以重复定义多个块变量。

            2.使用块类型定义函数参数,这样即可定义带块参数的函数。*/

        //使用typedef定义块类型

        typedef void (^FKPrintBlock) (NSString*);

        //使用FKPrintBlock定义块变量,并将指定块赋给该变量

        FKPrintBlock printt = ^(NSString * info){

            NSLog(@"%@" , info);

        };

        //使用FKPrintBlock定义块变量,并将指定块赋值给该变量

        FKPrintBlock loopPrint = ^(NSString * info){

            for (int i = 0 ; i < 2 ; i++){

                NSLog(@"%@" , info);

            }

        };

        //一次调用两个块

        printt(@"Objective-C");

        loopPrint(@"iOS");

         

#pragma mark - 作为方法的参数

        /*作为方法声明的参数

         //- (void)方法名:(返回值类型 (^)(参数类型))block的名称;

         - (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;

        */

        NSArray *jingse = @[@"锦瑟无端五十弦,",@"一弦一柱思华年。",@"庄生晓梦迷蝴蝶,",@"望帝春心托杜鹃。",@"沧海月明珠有泪,",@"蓝田日暖玉生烟",@1,@NO];

        //定义一个block块操作 return(^fpointer)(int,NS*...) = ^(int a,NS* B...){...};

        void (^Pblock1)(id,NSUInteger,BOOL*) = ^(id obj,NSUInteger idx,BOOL *stop){

            NSLog(@"%ld --> %@",idx,obj);

            if (idx == [jingse count]) {

                *stop = YES;

            }

        };

        //匿名block指针

        [jingse enumerateObjectsUsingBlock:Pblock1];

        //- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop));

 

        //?????

//        BOOL *stop = NO;

//        for (int i = 0 ; stop; i++)

//            Pblock1(jingse[i],i,stop);

         

#pragma mark - 块的内存管理

        /*1)在运行程序时,块常量表达式会获得栈内存,因而会拥有与局部变量相同的生命周期。

        因此,它们您必须被复制到永久存储区域(即堆)中,才能在定义它们的范围之外使用。

          2)使用Block_copy()命令可以将块常量复制到堆中,使用Block_release()命令可以释放堆中的块常量.

          3)在使用ARC时,只要块没有返回id类型值或将id类型值用作参数,编译器就会自动执行块的复制和释放操作。否则,就必须手动执行复制和释放操作。

          4)在使用MRR时,__block变量不会被保留;而在使用ARC时,__block变量会被保留。这就意味着如果你在使用ARC时不想不想保留__block变量(如避免循环引用),还应对变量应用__weak存储类型修饰符*/

        /*在MRR下使用

         void (^greetingBlock)(void)

        {

            greetingBlock = [^{

                NSLog(@"Hello Jabit");

            } copy];

        }

        greetingBlock();

        [greetingBlock release];*/

         

        /*在MRR下使用

        void (^greetingBlock)(id salutation);

        {

            greetingBlock = Block_copy(^(id salutation){

                NSLog(@"%@, Jabit", salutation);

            });

        }

        greetingBlock(@"Hello");

        Block_release(greetingBlock);*/

         

#pragma mark - 在OC中使用block

        /*1、作为变量

         //1

         返回值类型 (^block的名称)(参数类型) = ^返回值类型(参数) {...};

         //2

         returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};

          

         2、作为属性

         //1

         @property (nonatomic, copy) 返回值类型 (^block的名称)(参数类型);

         //2

         @property (nonatomic, copy) returnType (^blockName)(parameterTypes);

          

         3、作为方法声明的参数

         //1

         - (void)方法名:(返回值类型 (^)(参数类型))block的名称;

         //2

         - (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;

          

         4、作为方法实现的参数

         //1

         [对象/类 方法名:^返回值类型 (参数) {...}];

         //2

         [someObject someMethodThatTakesABlock:^returnType (parameters) {...}];

          

         5、使用typedef定义块类型

        */

         

#pragma mark - 使用块为数组排序

#define ArrayElements 10

        //创建一个含有随机数值(0~99)的数组

        NSMutableArray *numbers = [NSMutableArray arrayWithCapacity:ArrayElements];

        for (int elem=0; elem<ArrayElements; elem++) {

            unsigned int value = arc4random() % 100;

            [numbers addObject:[NSNumber numberWithUnsignedInt:value]];

        }

        NSLog(@"Values:%@", numbers);       //记录未排序的数值

         

        //以升序方式为数组数值排序

        [numbers sortUsingComparator:^(id obj1, id obj2){

            if ([obj1 integerValue] > [obj2 integerValue]) {

                return (NSComparisonResult)NSOrderedDescending;

            }

            if ([obj1 integerValue] < [obj2 integerValue]) {

                return (NSComparisonResult)NSOrderedAscending;

            }

            return (NSComparisonResult)NSOrderedSame;

        }];

        NSLog(@"Values:%@", numbers);       //记录已排序的数值

         

#pragma mark - 使用块加载URL

#define IndexURL @"http://www.wikipedia.com/index.html"

        //为连接获取当前的运行循环

        NSRunLoop *loop = [NSRunLoop currentRunLoop];

        BOOL __block downloadComplete = NO;

         

        //创建请求

        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:IndexURL]];

        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){

            if (data == nil) {

                NSLog(@"Error loading request %@", [error localizedDescription]);

            }

            else {

                NSLog(@"\n\tDownloaded %lu bytes from request %@\n", [data length], [request URL]);

            }

            downloadComplete = YES;

        }];

         

        //一直循环直到完成加载资源的操作为止(它会运行循环,接收输入源的事件,并执行所有相应的委托或回调方法,直到连接完成加载资源的操作为止

        while (!downloadComplete && [loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

         

#pragma mark - 使用块的并行编程方式

#define YahooURL    @"http://www.yahoo.com/index.html"

#define ApressURL   @"http://www.apress.com/index.html"

        //创建任务请求(GCD API)

        dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

         

        //创建任务分组

        dispatch_group_t group = dispatch_group_create();

         

        //获取度量的当前时间

        NSDate *startTime = [NSDate date];

         

        //创建并分派异步任务

        dispatch_group_async(group, queue1, getDownloadURLBlock(YahooURL));

        dispatch_group_async(group, queue2, getDownloadURLBlock(ApressURL));

         

        //使主进程等待,直到分组中的所有任务完成为止

        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

         

        //为并行操作和日志检索时间信息

        NSDate *endTime = [NSDate date];

        NSTimeInterval timeInterval = [endTime timeIntervalSinceDate:startTime];

        NSLog(@"Time taken to download URLs concurrently = %f seconds\n", timeInterval);

    }

    return 0;

}

时间: 2024-10-28 13:24:40

Block的使用的相关文章

CSS魔法堂:不得不说的Containing Block

前言  <CSS魔法堂:重新认识Box Model.IFC.BFC和Collapsing margins>中提到在没有floated兄弟盒子时,line box的左右边框会与所属的containing block的左右content edge相接触.那到底什么是containing block(abbr. CB)呢? containing block在CSS的visual formatting model中十分重要的理论基础,因为盒子的宽/高度自动值/相对值的计算,相对/浮动/绝对定位,均依赖

ARC中block块作为属性的使用笔记

ARC中block块作为属性的使用笔记 block较难理解,根据在内存中的分布情况就分为3种类型,根据使用的情形又分为很多很多种.虽然用起来容易,但使用不当会造成内存泄露,虽然都是这么说,但你真的研究过为什么会泄露吗?为什么有些时候外部变量进入block的时候会导致引用计数+1呢?   本人做过MRC以及ARC的开发,但大势所趋,ARC将是以后开发的主要模式,即使有MRC也是ARC混编MRC的代码,所以,本文的block的一些使用上的心得都基于ARC的,已经不考虑MRC的了,请看官注意,MRC与

ARC下block使用情况

ARC与MRC的block有着一些区别,笔记整理ARC的block,仅仅是自己参考的笔记,详情请参考 http://www.cnbluebox.com/?p=255   在开始之前,请新建一个Model类,写几个如下的属性,用于后面测试block的特性.     Block的类型与内存管理 根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock. NSGlobalBlock:类似函数,位于text段: NSStackBlock:

UIButton的两种block传值方式

UIButton的两种block传值方式 方式1 - 作为属性来传值 BlockView.h 与 BlockView.m // // BlockView.h // Block // // Created by YouXianMing on 15/1/14. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import <UIKit/UIKit.h> @class BlockView; /** 定义枚举值 */ typed

CSS教程:block element与inline element元素详解

块元素(block element)一般是其他元素的容器元素,块元素一般都从新行开始,它可以容纳内联元素和其他块元素,常见块元素是段落标签'P"."form"这个块元素比较特殊,它只能用来容纳其他块元素. 如果没有css的作用,块元素会顺序以每次另起一行的方式一直往下排.而有了css以后,我们可以改变这种html的默认布局模式,把块元素摆放到你想要的位置上去.而不是每次都愚蠢的另起一行.需要指出的是,table标签也是块元素的一种,table based layout和css

块(Block),元素(Element),修饰符(Modifier)

文章简介:BEM代表块(Block),元素(Element),修饰符(Modifier).这些术语的含意将在本文进一步阐述. 什么是BEM? BEM代表块(Block),元素(Element),修饰符(Modifier).这些术语的含意将在本文进一步阐述. 编程方法论中一个最常见的例子就是面向对象编程(OOP).这一编程范例出现在许多语言中.在某种程度上,BEM和OOP是相似的.它是一种用代码和一系列模式来描述现实情况的方法,它只考虑程序实体而无所谓使用什么编程语言. 我们使用BEM的原则创建了

内联元素(inline element)和块元素(block element)

文章简介:CSS里有哪些常见的块级元素和行内元素?  根据CSS规范的规定,每一个网页元素都有一个display属性,用于确定该元素的类型,每一个元素都有默认的display属性值,比如div元素,它的默认display属性值为"block",成为"块级"元素(block-level):而span元素的默认display属性值为"inline",称为"行内"元素. div这样的块级元素,就会自动占据一定矩形空间,可以通过设置高

关于执行计划里recursive calls,db block gets和consistent gets参数的解释

执行 我们在实际工作中经常要看某个sql语句的执行计划,例如: 在sqlplus使用命令SET AUTOTRACE ON后,执行计划显示如下: SELECT STATEMENT Optimizer=ALL_ROWS (Cost=985 Card=1 Bytes=26) Statistics----------------------------------------------------------35 recursive calls0 db block gets1052 consisten

block(块元素)、inline(内联元素)的差别是什么?

我们首先要了解,所有的html元素,都要么是block(块元素).要么是inline(内联元素).下面了解一下block.inline各自的特点: block元素的特点: 总是在新行上开始: 高度,行高以及顶和底边距都可控制: 宽度缺省是它的容器的100%,除非设定一个宽度. inline元素的特点: 和其他元素都在一行上: 高,行高及顶和底边距不可改变: 宽度就是它的文字或图片的宽度,不可改变. 我们来详细了解它们的情况. 块元素(block element)一般是其他元素的容器元素,块元素一

使用PHP4中的 IntegratedTemplate类实现BLOCK功能

使用PHP 模板类进行编程很有好处,但是有时也会碰到一个问题,比如说输出一个表格,但是表格行数要到运行的时候才知道,如留言板.BBS.购物网站之类,经常会碰到这个问题.这时做美工的人无法决定在HTML文件中用几行表格,如果在PHP代码文件中写循环输出,又会让美工.PHP程序员看代码都不方便,美工的人会说,这里的表格哪里去了?我要修改表格的颜色背景之类怎么办?PHP程序员也会说,怎么这里突然有一个<tr>.<td>,做什么用?会嵌在HTML文件哪里?. 使用PHP模板类编程一般把这种