热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

block初步认识

最近了解了一下block的应用(其实早该掌握了),然后稍微整理了一下。Block是一个CLevel的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编

最近了解了一下block的应用 (其实早该掌握了 ,) ,然后稍微整理了一下。

Block 是一个C Level的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,从iOS4.0开始就很好的支持Block.

block的好处,主要1.用于回调特别方便, 2. 可以延长对象的作用区域。(__block关键字,将局部变量转变为全局变量)。但是block默认都是分配在stack上面的,即栈上面,所以它的作用区域就是当前函数。 

可以延长对象的作用域这块就不说了,主要说下用于回调。关于block用于回调这点,因为代理也可以实现其相同的功能。故我将block和delegate代理做了一下对比,发现,岂止相似,简直TMD相似.此处我举得例子是“狗和人的事情“,即看门狗发现敌情向人汇报。。

首先看block

定义两个类: Dog.h    Person.h

Dog.h

@interface Dog : NSObject

{

    int _ID;     //id编号

    NSTimer *timer;    //启动一个定时器

    int barkCount;    //狗叫的次数,也是向主人汇报的次数

    

    //定义一个blocks变量

    void (^BarkCallback) (Dog *thisDog, int count);

}

@property (assign) int ID;


//Person 用的

//向外暴露了一个函数  setBark

- (void) setBark:(void (^) (Dog *thisDog, int count)) eachBark;


@end


Dog.m:

#import "Dog.h"

@implementation Dog

//重写init方法,开启一个定时器,每隔1s向主人汇报情况

- (id)init

{

    self = [super init];

    if (self) {

        timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];

    }

    return self;

}


- (void) updateTimer:(id)arg

{

    barkCount++;

    NSLog(@"dog %d bark count %d",_ID, barkCount);

        

    //Person/xiaoLi汇报一下 (进行通讯)

    //调用Person/xiaoLi 里的blocks

    if (BarkCallback) {

        BarkCallback(self, barkCount);

    }    

}


- (void) setBark:(void (^) (Dog *thisDog, int count)) eachBark

{

    //从Person接收过来block

    BarkCallback = eachBark;

}


Person.h:

#import

#import "Dog.h"


@interface Person : NSObject

@property (nonatomic,retain)Dog *dog;

@end



Person.m:

#import "Person.h"


@implementation Person

- (void)setDog:(Dog *)dog

{    

    [dog setBark:^(Dog *dog, int barkCount) {

        NSLog(@"Person, dog %d bark %d",dog.ID, barkCount);

    }];   

}

@end


在控制器里面调用:

     Dog *dog = [[Dog alloc] init];

    dog.ID = 10;

    

    Person *person = [[Person alloc] init];

    person.dog = dog;

跑一下程序,看打印:

2014-12-17 19:28:48.727 BlockDemo-2[2752:199621] dog 10 bark 1

2014-12-17 19:28:48.728 BlockDemo-2[2752:199621] Person, Dog 10 bark 1

2014-12-17 19:28:49.728 BlockDemo-2[2752:199621] dog 10 bark 2

2014-12-17 19:28:49.728 BlockDemo-2[2752:199621] Person, Dog 10 bark 2

2014-12-17 19:28:50.727 BlockDemo-2[2752:199621] dog 10 bark 3

2014-12-17 19:28:50.727 BlockDemo-2[2752:199621] Person, Dog 10 bark 3

......


 下面看下代理

同样:Dog.h:

#import


@class Dog;


@protocol barkCallBack <NSObject>


- (void)barkCallBackToPerson:(Dog *)dog andCount:(int)barkCount;


@end


@interface Dog : NSObject

{

    int _ID;

    NSTimer *timer;

    int barkCount;

}


@property (assign) int ID;


@property (assign) id <barkCallBack> delegate;


@end


Dog.m:

#import "Dog.h"


@implementation Dog

- (instancetype)init

{

    self = [super init];

    if (self) {

        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];

    }


    return self;

}


- (void)updateTimer:(id)arg

{

    barkCount++;

    NSLog(@"dog %d bark count %d",_ID, barkCount);

    if ([_delegate respondsToSelector:@selector(barkCallBackToPerson:andCount:)]) {

        [_delegate barkCallBackToPerson:self andCount:barkCount];

    }

}


@end


Person.h:

#import

#import "Dog.h"


@interface Person : NSObject

@property (nonatomic,retain) Dog *dog;

@end


Person.m:

#import "Person.h"


@implementation Person


- (void) setDog:(Dog *)dog

{

    dog.delegate = (id)self;

}


- (void)barkCallBackToPerson:(Dog *)dog andCount:(int)barkCount

{

    NSLog(@"person  dog %d  bark %d",[dog ID], barkCount);

}

@end


在控制器里:

    Person *xiaoLi = [[Person alloc] init];

    Dog *dog = [[Dog alloc] init];

    [dog setID:10];

    [xiaoLi setDog:dog];

    

    [[NSRunLoop currentRunLoop] run];   //此时,需要注意加上这句代码,不然程序会崩。不加也可以,但是要改其他地方。具体为什么,没弄懂,哈哈~~ 望高手赐教。

跑一下看看打印结果:

2014-12-17 19:53:35.092 DelegateDemo-Dog[3366:213877] dog 10 bark count 1

2014-12-17 19:53:35.093 DelegateDemo-Dog[3366:213877] person  dog 10  bark 1

2014-12-17 19:53:36.091 DelegateDemo-Dog[3366:213877] dog 10 bark count 2

2014-12-17 19:53:36.091 DelegateDemo-Dog[3366:213877] person  dog 10  bark 2

2014-12-17 19:53:37.092 DelegateDemo-Dog[3366:213877] dog 10 bark count 3

2014-12-17 19:53:37.092 DelegateDemo-Dog[3366:213877] person  dog 10  bark 3

......

一模一样


当然,你也可以在刚才的block程序里面或者delegate程序里面把Person.h去掉,直接在控制器里执行回调或者代理方法也行,让狗汇报情况。具体怎么实现都行。












block初步认识


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
author-avatar
渊博的效力
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有