博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Block的使用
阅读量:6810 次
发布时间:2019-06-26

本文共 8287 字,大约阅读时间需要 27 分钟。

  hot3.png

Block:

//  main.m//  块的使用#import 
#include 
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
 [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;}

转载于:https://my.oschina.net/Jacedy/blog/620651

你可能感兴趣的文章
Liferay中actionURL能够执行后台方法 ,但是页面不跳转问题解决方案
查看>>
libyuv 编译for ios
查看>>
加密安装Kali Linux条件
查看>>
关于Cocos2d-x中UI按钮的定义
查看>>
IPTables系列:如何配置Ubuntu 14.04中的IPTables防火墙
查看>>
swift:自定义UICollectionViewFlowLayout
查看>>
转】MYSQL性能调优与架构设计之select count(*)的思考
查看>>
MFC Initinstance中DoModal()返回-1
查看>>
抢红包的红包生成算法
查看>>
1 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之DRBD的搭建
查看>>
升级到 PHP-7 遇到的坑 及 经验分享
查看>>
Android 关于ListView中adapter调用notifyDataSetChanged无效的原因
查看>>
redis哨兵配置
查看>>
VC++/MFC 最常用宏和指令
查看>>
外国javascript资源搜索
查看>>
DataTable中数据针对某列数据去重
查看>>
ASP.NET MVC防范CSRF最佳实践
查看>>
[LintCode] Max Points on a Line 共线点个数
查看>>
GIt的基本知识
查看>>
分享一款CSS框架
查看>>