ios 中的block应用

在这个大冬天里默默敲着键盘,勿喷.今天学习swift过程中,学习到闭包,发现闭包和oc的block中有很多的相同之处,又重新学习了一下并且学习了一些高级点的用法,内容如下:

1.block格式说明:(返回类型)(^块名称)(参数类型) = ^(参数列表) {代码实现};//如果没有参数,等号后面参数列表的()可以省略

例子:

void(^demoBlock)() = ^ {

NSLog(@"demo Block");

};

int(^sumBlock)(int, int) = ^(int x, int y) {

return x + y;

};

2.block中使用的变量将以复制的形式保留,在block中保留block的复制的变量,默认情况下,Block外部的变量,在Block中是只读的!当使用__block关键字后,同样可以在Block中修改外部变量的数值.

3.可以使用typedef定义一个Block的类型,便于在后续直接使用,如:

typedef double(^MyBlock)(double, double);

MyBlock area = ^(double x, double y) {

return x * y;

};

MyBlock sum = ^(double a, double b) {

return a + b;

};

NSLog(@"%.2f", area(10.0, 20.0));

NSLog(@"%.2f", sum(10.0, 20.0));

4.尽管,typedef可以简化Block的定义,但在实际开发中并不会频繁使用typedef关键字,这是因为Block具有非常强的灵活性,尤其在以参数传递时,使用Block的目的就是为了立即使用

官方的数组遍历方法声明如下:

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;

而如果使用typedef,则需要:

(1)typedef void(^EnumerateBlock)(id obj, NSUInteger idx, BOOL *stop);

(2)- (void)enumerateObjectsUsingBlock:(EnumerateBlock)block;

而最终的结果却是,除了定义类型之外,EnumerateBlock并没有其他用处

5.Block可以被当做参数直接传递

NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"];

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

NSLog(@"第 %d 项内容是 %@", (int)idx, obj);

if ([@"王五" isEqualToString:obj]) {

*stop = YES;

}

}];

或者:

MyBlock sumBlock = ^(double x, double y) {
    return x * y;
    
};

- (void)add:(int)number withNumber:(int)withNumber sumBlock:(MyBlock) block
{
   
    NSLog(@"执行add:(int)number withNumber:(int)withNumber sumBlock:(void (^)(void))block");
    NSLog(@"hahaha--4和2相乘等于:%f",block(number,withNumber));

}

[self add:4 withNumber:2 sumBlock:sumBlock];

6.既然Block是一种数据类型,那么可以将Block当做比较特殊的对象,添加到数组

#pragma mark 定义并添加到数组

@property (nonatomic, strong) NSMutableArray *myBlocks;

int(^sum)(int, int) = ^(int x, int y) {

return [self sum:x y:y];

};

[self.myBlocks addObject:sum];

int(^area)(int, int) = ^(int x, int y) {

return [self area:x y:y];

};

[self.myBlocks addObject:area];

#pragma mark 调用保存在数组中的Block

int(^func)(int, int) = self.myBlocks[index];

return func(x, y);

7.解除循环引用

局部变量默认都是强引用的,离开其所在的作用域之后就会被释放

使用__weak关键字,可以将局部变量声明为弱引用

__weak DemoObj *weakSelf = self;

n在Block中引用weakSelf,则Block不会再对self做强引用

int(^sum)(int, int) = ^(int x, int y) {

return [weakSelf sum:x y:y];

};

8.今天重点,参考AFN的框架,block根据函数判断正确与否调用success或者failure函数参数,并传入参数.如下:

//由于主要还是用来判断success和failure函数,所以看着不舒服的同学可以自行脑补,将success换成add,将failure换成multiplied

- (void)viewDidLoad {
    [super viewDidLoad];
    self.isbool = true;//当isbool等于true的时候就相加,否则就相乘
 
    [self setCompletionBlockWithSuccess:^(int x,int y) {
        NSLog(@"相加等于:%d",x+y);
       
       NSLog(@"success");
   
       
    } failure:^(int x,int y) {
        
        NSLog(@"相乘等于:%d",x*y);
        NSLog(@"failure");
        
    
    }];

}

- (void)setCompletionBlock:(void (^)(void))block {
 
        block();
    NSLog(@"setCompletionBlock number2:%d number3:%d",self.number2,self.number3);
}

- (void)setCompletionBlockWithSuccess:(void (^)(int x,int y))success
                              failure:(void (^)(int x,int y))failure
{

self.completionBlock = ^{
    
         self.number2 = 10;
         self.number3 = 20;

if (self.isbool == true) {//判断传入哪个参数,执行success还是failure
             NSLog(@"开始相加");
             success(self.number2,self.number3);//参数传入setCompletionBlockWithSuccess
         }else{
              NSLog(@"开始相乘");
             failure(self.number2,self.number3);//参数传入setCompletionBlockWithSuccess
         }
     };

}

时间: 2024-10-24 09:26:17

ios 中的block应用的相关文章

如何在iOS中使用Block

如何在iOS中使用Block Block可以帮助我们组织独立的代码段,并提高复用性和可读性.iOS4在UIKit中引入了该特征.超过100个的Apple API都使用了Block,所以这是一个我们必须开始熟悉的知识. Block是什么样的? 你可以使用^操作符来声明一个Block变量,它表示一个Block的开始. int num1 = 7; int(^aBlock)(int) = ^)int num2) { return num1+nunm2; }; 在如上代码中我们将Block声明为一个变量,

iOS中使用block进行网络请求回调

iOS中使用block进行网络请求回调 HttpRequest.h // // HttpRequest.h // UseBlockCallBack // // Created by Michael on 2/13/14. // Copyright (c) 2014 EIMS. All rights reserved. // #import <Foundation/Foundation.h> typedef void (^FinishBlock)(NSString *dataString); @

IOS中的Block与C++11中的lambda

ios中的block 可以说是一种函数指针,但更确切的讲,其实际上其应该算是object-c对C++11中lambda的支持或者说是一个语言上的变体,其实际内容是一样的,C++的lambda我已经有简介过,现在说下ios中的block Block的实际行为和Function很像,最大的差别是在可以存取同一个Scope的变量值.Block实体形式如下: ^(传入参数列){行为主体}; Block实体开头是“^”,接着是由小括号所包起来的参数列(比如 int a, int b, int c),ret

iOS中为什么block用copy属性

1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC下返回Block).另一个需要注意的问题是关于线程安全,在声明Block属性时需要确认“在调用Block时另一个线程有没有可能去修改Block?”这个问题,如果确定不会有这种情况发生的话,那么Block属性声明可以用nonatomic.如果不肯定的话(通常情况是这样的),那么你首先需要声明Block

IOS中的block 循环引用和retain cycle (经典)

retain cycle 的产生 说到retain cycle,首先要提一下Objective-C的内存管理机制. 作为C语言的超集,Objective-C延续了C语言中手动管理内存的方式,但是区别于C++的极其非人道的内存管理,Objective-C提出了一些机制来减少内存管理的难度. 比如:内存计数. 在Objective-C中,凡是继承自NSObject的类都提供了两种方法,retain和release.当我们调用一个对象的retain时,这个对象的内存计数加1,反之,当我们调用relea

iOS中的block

定义一个block: int (^blockname)(int, int); blockname = ^(int a, int b){ return a>b ? a: b; }; 这个block等同于: int  (^blockname)(int, int) = ^(int a, int b){ return a>b?a:b; }; 使用: NSInterge a = blockname(3, 4); NSLog(@"a=%ld", a); .block作为方法的参数   

iOS中使用block传值

转自:http://blog.sina.com.cn/s/blog_60b45f230100yiaf.html 用此方法传值可以替代委托了.具体例子: MainView.h #import <UIKit/UIKit.h> @interface MainView : UIViewController { IBOutlet UIButton* btn; IBOutlet UILabel* labShow; } -(IBAction)push:(id)sender; @end MainView.m

iOS中消息的传递机制(KVO、Notification、delegation、block以及target-action)---转载

注1:本文由破船[博客]译自Communication Patterns. 本文目录如下所示: 可用的机制 做出正确的选择 Framework示例 小结 每个应用程序或多或少,都由一些松耦合的对象构成,这些对象彼此之间要想很好的完成任务,就需要进行消息传递.本文将介绍所有可用的消息传递机制,并通过示例来介绍这些机制在苹果的Framework中如何使用,同时,还介绍了一些最佳实践建议,告诉你什么时机该选择使用什么机制. 虽然这一期的主题是关于Foundation Framework的,不过本文中还

iOS中block类型大全

iOS中block类型大全 typedef的block 作为属性的block 作为变量的block 作为方法变量入参的block 作为方法参数的block 无名block 内联函数的block 递归调用的block 作为方法返回值的block 作为函数名的block(太过奇葩,完全不知道怎么用-_-!) iOS中block类型大全,码迷,mamicode.com