码迷,mamicode.com
首页 > 其他好文 > 详细

Block块

时间:2016-04-28 23:49:00      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:

block的标志:^
特点:
1、可以保存代码
2、有返回值
3、有形参
4、调用方式和c语言一样
5、可以访问外部变量,但不能修改变量的值;如果使用__block关键字修饰的变量才可以。
1)创建
格式:
返回类型  ^block名称(参数类型表)=^(参数表){
     代码;
};
block跟函数很像
a、不带参数
void (^myBlock)()=^{
     NSLog(@“…000”);
};
b、带参数
int(^sumBlock)(int,int)=^(int a,int b){
     return a+b;
}
c、用typedef定义block变量
typedef int(^)
定义block变量:
typedef int(^myblock)(int,int);
实现(重写):
myblock sblock = ^(int a,int b){
     return a+b;
}
myblock subblock = ^(int a,int b){
     return a-b;
}
使用:
NSLog(@“a+b = %d”,sblock(1,2));
NSLog(@“a+b = %d”,subblock(5,2));
 
技术分享
 
如:
//定义一个带block参数的函数
-(void)xxxxxxx:(void(^)(NSString *strr))finishBlock{
    NSLog(@"xxxxxxxx");
    finishBlock(@"........");
    NSLog(@"jjjjjjjj");
}
//调用
- (IBAction)Blockaction:(UIButton *)sender {
    [self xxxxxxx:^(NSString *strr) {
        NSLog(@"%@",strr);
    }];
}
结果:
技术分享
 
 
6、Block的循环引用 
1)__weak:表示引用为弱引用。对应在定义property时用的"weak"。弱引用不会影响对象的释放,即只要对象没有任何强引用指向,即使有100个弱引用对象指向也没用,该对象依然会被释放。不过好在,对象在被释放的同时,指向它的弱引用会自动被置nil,这个技术叫zeroing weak pointer。这样有效得防止无效指针、野指针的产生。__weak一般用在delegate关系中防止循环引用或者用来修饰指向由Interface Builder编辑与生成的UI控件。
2)__strong:表示引用为强引用。对应在定义property时的"strong"。所有对象只有当没有任何一个强引用指向时,才会被释放。

注意:如果在声明引用时不加修饰符,那么引用将默认是强引用。当需要释放强引用指向的对象时,需要将强引用置nil。

一个特别要注意的问题

苹果的文档中明确地写道:

You should decorate variables correctly. When using qualifiers in an object variable declaration,

the correct format is:

ClassName * qualifier variableName;

按照这个说明,要定义一个weak型的NSString引用,它的写法应该是:

NSString * __weak str = @"hehe"; // 正确!

而不应该是:
__weak NSString *str = @"hehe";  // 错误!
 
对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block
对于ARC下, 为了防止循环引用, 我们使用__weak来修饰在Block。原理就是:ARC中,Block中如果引用了__strong修饰符的自动变量,则相当于Block对该变量的引用计数+1

不过好在,编译器会及时地给我们一个警告,提醒我们可能会发生这类型的问题:

技术分享

对这种情况,我们一般用如下方法解决:给要进入Block的指针加一个__block修饰符。

这个__block在MRC时代有两个作用:

  • 说明变量可改
  • 说明指针指向的对象不做这个隐式的retain操作 
一个变量如果不加__block,是不能在Block里面修改的,不过这里有一个例外:static的变量和全局变量不需要加__block就可以在Block中修改。
在ARC引入后,没有了retain和release等操作,情况也发生了改变:在任何情况下,__block修饰符的作用只有上面的第一条:说明变量可改。即使加上了__block修饰符,一个被block捕获的强引用也依然是一个强引用。
#include <stdio.h>

int main()
{
    int b = 5;
    int *a = &b;
    void (^blockFunc)() = ^(){
        int *c = a;
    };
    
    blockFunc();
    
    return 1;
}
程序中,同为int型的指针,a是被Block捕获的变量,而c是在Block内定义的变量。a和c存在的位置完全不同,如果Block存在于堆上(在ARC下Block默认在堆上),那么a作为Block结构体的一个成员,也自然会存在于堆上,而c无论如何,永远位于Block内实际执行代码的函数栈内。这也导致了两个变量生命周期的完全不同:c在Block的函数运行完毕,即会被释放,而a呢,只有在Block被从堆上释放的时候才会释放。
同上理,如果我们直接让Block捕获我们的myController引用,那么这个引用会被复制后(引用类型也会被复制)作为Block的成员变量存在于其所在的堆空间中,也就是为Block增加了一个指向myController对象的强引用,这就是造成循环引用的本质原因。
 
//------------------------------------------------------------------------------------

 

Block块

标签:

原文地址:http://www.cnblogs.com/lignpeng/p/5444674.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!