ios 自定义bolck以及block注意事项

本文详细介绍了Objective-C中block的定义、如何提供访问接口、反向传参的方法、如何接收传参以及避免retain cycle的问题。通过实例演示了如何在不同控制器间传递数据,并讨论了block在调用方法时可能引发的内存泄露问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文将介绍一下block的反向传值以及block使用的注意事项。

1.block定义

一般在.h文件中用如下方式定义。

typedef returnType(^name)(arguments);
returnType参数:表示block代码块返回值,若没有返回值则为void,若有返回值,则根据返回值类型来决定

name参数:block代码块的名称,可自己命名

arguments参数:反向传值的参数,可多个,用逗号隔开

例:

typedef void(^callBackBlock)(NSString* str,int num);


2.提供block访问接口

接下来需要在.h文件中设置block属性,以提供接口给其他控制器访问。
@property (copy , nonatomic) callBackBlock myCallBackBlock;


3.反向传值

在调用block块之前,要先判断该block是否被引用。block块的括号内加入所传参数,参数类型需要符合自定义block时的传值类型

- (void) popViewController
{
    if (self.myCallBackBlock)
    {
        self.myCallBackBlock(@"My block",1010);
    }
    [self.navigationController popViewControllerAnimated: YES];
}


4.接受block所传值

实现viewController01中的block

- (void) push
{
    ViewController01* vc = [[ViewController01 alloc] init];
    vc.myCallBackBlock = ^(NSString* str1,int num){
        NSLog(@"%@ , %d",str1,num);
    };
    [self.navigationController pushViewController:vc animated:YES];
}
打印得到:

2015-02-06 10:40:40.428 OC_Test[1960:92579] My block , 1010


5.block中调用方法造成retain cycle

block会隐式地对进入其作用域内的对象(或者说被Block捕获的指针指向的对象)加retain,来确保Block使用到该对象时,能够正确的访问。

这样的代码是错误的:

ViewController01* vc = [[ViewController01 alloc] init];
vc.myCallBackBlock = ^(NSString* str1,int num){
        [vc test];
    };
vc在初始化的时候,retainCount为1。block中调用vc的test方法时,block会对vc再次retain,vc的retainCount变为2。ARC工程在合适的时候肯定会做一次隐式release或autoRelease,显然vc在release后的retainCount等于1,系统无法释放vc这部分资源(retainCount为0的时候才会释放),造成内存泄露。

正确写法:

ViewController01* vc = [[ViewController01 alloc] init];
    
    // 1.block中引用到的变量为了防止造成retain cycle,加__weak弱引用修饰
    __weak ViewController01* weakVc = vc;
    
    vc.myCallBackBlock = ^(NSString* str1,int num){
        
        // 2.为了避免多线程操作中弱引用提前释放
        ViewController01* strongVc = weakVc;
        
        [strongVc test];
    };
有人会问了,为什么在block内用了强引用strongVc而不会造成retain cycle呢?简单来讲,strongVc是block内定义的变量,block不会对他再retain一次。而对于在block内中引用外部的变量,block才会对该变量自动retain。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值