IOS优雅的Block语法

本文详细介绍了自iOS4.0起引入的Block语法在UIKit中的应用,包括线性遍历、方法回调和异步逻辑等方面。通过苹果官方实例展示了如何使用Block简化代码、提高模块化程度和实现异步操作。

自IOS4.0起加入Block语法,UIKit中超过一百个API使用了Block,主要用在线性遍历(简化代码,更好的抽象),方法回调(相比使用delegate模块化程度更高),异步逻辑(GCD框架下)。

在一些开源的项目里面也都提供支持Block语法的API,如ASIHttpRequest、Reachability等,更有专门扩展现有框架提供Block支持的Blockskit项目。很显然Block对于追求优雅是有很大帮助的。

关于Block实现原理,可以参看:http://blog.youkuaiyun.com/jasonblog/article/details/7756763 ,

关于递归和泛型的:http://blog.youkuaiyun.com/onlyou930/article/details/6999063,

在此不再累赘说明。

线性遍历

苹果官方例1:没有for循环的代码很美观嘛,Block内部可以使用作用域内的自由变量,申明为__block则会以传引用的方式使用

__block BOOL found = NO;  
NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];  
NSString *string = @"gamma";  

[aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {  
    if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {  
        *stop = YES;  
        found = YES;  
    }  
}]; 

苹果官方例2:可以看到compareStringsBlock是可以被很好的复用的

NSComperator compareStringsBlock = ^(id stringA, id stringB) {
    NSRange rangeS  = NSMakeRange(0, [stringA length]);
    return (stringA compare:stringB options:comparisonOptions range:rangeS locale:currentLocale];
};
NSArray *compareSortArray  = [arrayOfStringDays sortArrayUsingComparator:compareStringsBlock]);

方法回调

示例1:BlocksKit中对NSTimer的扩展,免去了在另外一个地方写个回调函数的麻烦。

// 启动计时操作
__block int _total = 0;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.1 block:^(NSTimeInterval time) {
    _total += 1;
    NSLog(@"total is %d", _total);
    // 这里更新UI界面 显示时间
} repeats:YES];

示例2:ASIHttpRequest中的例子,这里request要申明为__block是防止循环引用

- (IBAction)grabURLInBackground:(id)sender
{
    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
    __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    [request setCompletionBlock:^{
        // Use when fetching text data
        NSString *responseString = [request responseString];

        // Use when fetching binary data
        NSData *responseData = [request responseData];
    }];
    [request setFailedBlock:^{
        NSError *error = [request error];
    }];
    [request startAsynchronous];
}

GCD应用

示例1:方便的创建异步逻辑,并在异步逻辑执行完之后到主线程更新UI

[request setCompletionBlock:^{
    NSData *responseData = [request responseData];
    // 在并发任务队列(非主线程的一个线程池)解包数据并写入数据库
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        UniPacket *uniPacket = [UniPacket fromData:responseData];
        // 此处写入数据库,去除重复数据 并整理要显示的数据_finalDatas
        dispatch_async(dispatch_get_main_queue(), ^{
            // 在此处将finalDatas在主线程中更新到UI界面
        }
    });
}];

作用域问题

因为Block是分配在栈上面的C语言对象,所以要注意其作用域范围,下面的代码block调用是不正确的

同时我们也可以知道,如果要将Block作为函数参数传递的话,或者要异步使用的话,需要先将Block复制为堆上的对象

对于Block里面使用到的上下文对象,Block对象会将其retain一份,使用self访问成员变量和使用成员变量名访问,ratain的对象是不一样的,前者retain的是self,后者retain的是成员变量当前指向的对象

dispatch_block_t block;
if (x) {
    block = ^{ printf("true\n"); };
} else {
    block = ^{ printf("false\n"); };
}
block();

单例模式

既然扯远了,就再扯远点,下面是苹果公司引入的适合创建单例的一种方式

dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题

+ (ClassnName *)sharedInstance 
{
    static ClassnName *obj = nil;
    static dispatch_once_t pred;    
    dispatch_once(&pred, ^{ 
        obj = [[ClassnName alloc] init]; 
    });
    return obj;
}







Nano-ESG数据资源库的构建基于2023年初至2024年秋季期间采集的逾84万条新闻文本,从中系统提炼出企业环境、社会及治理维度的信息。其构建流程首先依据特定术语在德语与英语新闻平台上检索,初步锁定与德国DAX 40成分股企业相关联的报道。随后借助嵌入技术对文本段落执行去重操作,以降低内容冗余。继而采用GLiNER这一跨语言零样本实体识别系统,排除与目标企业无关的文档。在此基础上,通过GPT-3.5与GPT-4o等大规模语言模型对文本进行双重筛选:一方面判定其与ESG议题的相关性,另一方面生成简明的内容概要。最终环节由GPT-4o模型完成,它对每篇文献进行ESG情感倾向(正面、中性或负面)的判定,并标注所涉及的ESG具体维度,从而形成具备时序特征的ESG情感与维度标注数据集。 该数据集适用于多类企业可持续性研究,例如ESG情感趋势分析、ESG维度细分类别研究,以及企业可持续性事件的时序演变追踪。研究者可利用数据集内提供的新闻摘要、情感标签与维度分类,深入考察企业在不同时期的环境、社会及治理表现。此外,借助Bertopic等主题建模方法,能够从数据中识别出与企业相关的核心ESG议题,并观察这些议题随时间的演进轨迹。该资源以其开放获取特性与连续的时间覆盖,为探究企业可持续性表现的动态变化提供了系统化的数据基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值