您的位置:首页 > 移动开发 > IOS开发

iOS开法--block篇

2016-04-29 08:19 357 查看
Block

一、基本概念:

Block是一种C语言的数据类型,指向结构体的指针,平常我们将Block当作一个代码段使用,相当于函数,Block相比于函数的优点是 Block可以当做一个参数传递而函数/方法不能.。我们可以用Block写一些函数语句,可以使用多线程。Block也可以作为一个回调,不仅包含回调期间的代码,也包含了执行期间需要的数据。类似于"闭包",闭包的定义是可以c从函数外部访问函数内部的变量。

二、基本用法:

1)无参无返回值(最简单形式)

定义格式:void (^block名)() = ^{代码块;};

使用格式:block名();

2)无参有返回值(以返回值为int为例)

定义格式:int (^block名)() = ^{代码块;};

使用格式:int result = block名();

3)有参无返回值(以参数为int为例)

定义格式:void (^block名)(int) = ^(int a){代码块;};

使用格式:  block名(6);

4)有参有返回值(以参数、返回值为int为例;可以有多个参数)

定义格式:int (^block名)(int) = ^(int a){代码块;};

使用格式:int result = block名(6);

5)利用typedef定义block类型(和指向函数的指针很像)

定义格式:typedef 返回值类型(^新别名)(参数类型列表);

例:typedef int (^myBlock)(int,int);

三、Block访问外部变量

1)在block内部可以访问block外部的变量,但是,这是一个新的内存空间变量;

block内部也可以定义和block外部同名的变量,此时这个局部变量会屏蔽外部变量的作用域。

2)如果想要在block内部修改外部的局部变量,需要给该变量加上__block关键字;原因是加__block,block会引用常量变量的地址,则可以任意修改该变量指向的内容。如果不加__block直接在block内部修改变量,会编译报错,block内部变量是只读的。

四、Block使用技巧和注意事项

1)block的快速提示,输入inlineBlock 会有代码提示;

2)block变量用作方法的参数时,最好把参数类型列表部分加上具体的参数名

3)利用block遍历取值

例: [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key,
id _Nonnull obj,
BOOL *_Nonnull stop) {

}];

5)  block修饰:block的发展也经过了MRC和ARC两个阶段;

MRC情况下:用copy修饰后,如果要在block内部使用对象,则需要进行__block
typeof(Target) blockTarget = Target处理,在block里面用blockTarget 操作。

ARC情况下:如果用copy修饰,该block就会存储在堆空间以避免在使用时发生释放。
cdae
但会对block的内部对象进行强引用,导致循环引用,内存无法释放。 所以block使用self ,要使用
self 弱引用写法. 即__weaktypeof(self) weakSelf =self;如果用weak修饰block,该block就会存放在栈空间,虽不会出现循环引用,但容易造成需要使用对象时,对象已经不存在的问题,原因是存储在栈空间的各种数据是系统自动处理的,并不需要程序猿手动处理,所以我们也不知道对象什么时候会被释放。

6)循环引用

分析循环(VC代表viewController控制器,op代表一个操作)

已知 : op --> self(VC) 强引用

如果 self 强引用的对象,对 op 也有强用.那么就会有循环引用

self(VC) --> queue/OPCache --> op -->
self(VC)

所以block使用 self ,要使用
self 弱引用写法. 即__weak
typeof(self) weakSelf =
self;

GCD中的block(任务)出现self,会造成循环引用吗?   ----- GCD中的block可以直接使用self

block循环引用的条件: block------->强应用(self) 
self ------->强引用(block属性)

NSOperation 中的blcok中是否可以出现 self ?

一般情况下 NSOperationQueue 需要作为一个属性. 将操作添加到操作队列中!

注意: 1.确实会出现循环引用!

但是: 操作一旦执行完毕之后,就会被自动销毁! 所以 NSOperation 中可以出现 self.

7)block可以在两个对象之间进行传值,类似于代理和通知;

以POST请求为例,假如我在A对象中封装了POST请求的方法,该方法请求回来的数据想传递给B对象,就可以利用block实现:

代码示例:

"A对象中声明方法

//MARK:- 一句话封装POST请求

- (void)POSTRequestWithURLString:(NSString *)urlString andDict:(NSDictionary *)pramarts andSuccessBlock:(successBlock)successblock andFalseBlock:(falseBlock)falseblock ;

"实现方法

- (void)POSTRequestWithURLString:(NSString *)urlString andDict:(NSDictionary *)pramarts andSuccessBlock:(successBlock)successblock andFalseBlock:(falseBlock)falseblock {

    

    //MARK:- 创建请求

    NSURL *url = [NSURL URLWithString:urlString];

#warning - POST请求要创建可变请求

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:15];

    

    //MARK:- 设置请求体、请求方法等参数

    request.HTTPMethod = @"POST";

    NSMutableString *strM = [NSMutableString string];

    [pramarts enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key,
id _Nonnull obj,
BOOL *_Nonnull stop) {

        NSString *pramKey = key;

        NSString *pramValue = obj;

        [strM appendFormat:@"%@=%@&",pramKey,pramValue];

    }];

    NSString *pramart = [strM substringToIndex:strM.length-1];

    request.HTTPBody = [pramart dataUsingEncoding:NSUTF8StringEncoding];

    

    //MARK:- 发送请求

    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *_Nullable data, NSURLResponse *
_Nullable response, NSError *
_Nullable error) {

        

        if (data&&!error) {

            if (successblock!=nil) {//一定要先判断block是否为空

                successblock( obj,response);//回调

            }

        }else{

            if (falseblock!=nil) {//同上

                falseblock(error);

            }

        }

    }]resume];

}

"B对象调用方法

[[YQPOSTRequest sharedPOSTRequest] POSTRequestWithURLString:urlStr andDict:pram andSuccessBlock:^(NSData *data, NSURLResponse *response) {

    

    NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);

    

} andFalseBlock:^(NSError *error) {

    

    NSLog(@"%@",error);

    

}];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  OC iOS 数据