iOS关于block使用的注意和探讨

没有过多的研究block ,最近几天,有人提到了 使用block 有可能会出现内存泄露的问题,这个问题确实存在,如果不注意的话。

现在目前block内存泄露的原因,目前自己弄出了二个原因,一个是出现是引用循环,二就是 对象未被销毁。

引用循环这个问题还是比较的好控制,在block里面加弱引用,或者是用__block,要看具体情况。我主要是说一下第二点,我也看了 人家的博客仔细研究了一下

感觉别人没有说对,自己经过实践,总结了一下还有一些不明白的。

创建3个viewcontroller viewcontroller01  viewcontroller02  viewcontroller03


viewController01 跳转viewcontroller02 viewcontroller02 跳转到 viewcontroller03

我自己自定义了一个 button 主要是要调用delloc 的方法

viewcontroller02

@interface ViewController ()

{

    UIButton *button;

//   __block ImButton * im;

}

//自定义 button 

@property (nonatomic,strong)ImButton *im;


@end


@implementation ViewController

@synthesize im;


- (void)viewDidLoad {

    [superviewDidLoad];

   //一个返回按钮一个 进入下个controller的按钮 

    button = [[UIButtonalloc]initWithFrame:CGRectMake(100,200, 50,50)];

    button.backgroundColor = [UIColorgrayColor];

    self.view.backgroundColor = [UIColorwhiteColor];

    [self.view addSubview:button];

    

    [buttonaddTarget:selfaction:@selector(buttonAction)forControlEvents:UIControlEventTouchUpInside];

    

    im = [[ImButtonalloc]initWithFrame:CGRectMake(100,100, 50,50)];

    

    im.backgroundColor=[UIColorblackColor];

    [imaddTarget:selfaction:@selector(rele)forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:im];

    

    // Do any additional setup after loading the view, typically from a nib.

}


-(void)rele{


    [selfdismissViewControllerAnimated:YEScompletion:nil];

}


-(void)buttonAction{

    

    ViewController03 *viewcontroller03 = [[ViewController03 alloc]init];

   //打印引用计数

    NSLog(@"1------%p---%ld",im,CFGetRetainCount((__bridgeCFTypeRef)im));

    [viewcontroller03 setBlock:^{

        im.backgroundColor = [UIColorblueColor];

    }];

    [selfpresentViewController:viewcontroller03 animated:YEScompletion:nil];

}


然后就是viewcontroller03

这是一种会出现内存泄露的情况 原因还在研究中

//就是这样定义block 会出现很坑人的情况就是 会出现viewcontroller2中的那个button不会释放掉 而且viewcontroller2 也不会释放掉

我尝试几种方法

void (^myblock)();

@implementation ViewController03

-(void)setBlock:(void(^)())block{

    myblock = block;

}


- (void)viewDidLoad {

    [superviewDidLoad];

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

- (IBAction)buttonAction:(id)sender {

    myblock();

    [selfdismissViewControllerAnimated:YEScompletion:nil];

    

}

-(void)dealloc{

    NSLog(@"delloc%@",self.class);

}


//解决方案一

-(void)buttonAction{

    

    ViewController02 *viewcontroller02 = [[ViewController02alloc]init];

    NSLog(@"1------%p---%ld",im,CFGetRetainCount((__bridgeCFTypeRef)im));

    __weak UIButton *imbutton =im;

//__block    UIButton *imbutton = im; //如果使用__block 需要将imbutton 变为空 如果不为nil会导致button引用计数加一并且viewcontroller02 退出后 button不会被释放 viewcontroller02 会被释放 我擦 好神奇


    [viewcontroller02 setBlock:^{

        imbutton.backgroundColor = [UIColorblueColor];

//        imbutton = nil;

    }];

    [selfpresentViewController:viewcontroller02 animated:YEScompletion:nil];

}


//解决方案二 这个是我最不能理解的了 让我不得不去研究变量,属性这些东西了

viewcontroller03.h的定义block


typedef void(^Myblock)();


@interface ViewController02 : UIViewController


-(void)setBlock:(void(^)())block;


//设置成为一个属性 然后viewcontroller02 和最上面的代码一样 这样居然不会内存泄露 有的时候我很难理解。这也是需要去研究和 思考的问题

@property (nonatomic,strong)Myblock myblock;


在开发的过程中还有很多这种自己感觉很神奇的情况,有的时候现在的知识储备难以去解释这是为什么,但是很多时候要养成一些好的习惯

每个类里面最好都写上dealloc,里面可以什么都没有,遇到有block的最好在dealloc里面输出一些信息,看是否是被释放了。这样还是会比较的保险一些

目前就是研究了这些 。

经过研究 发现这个跟变量的生命周期有关系,这样定义应该属于全局变量,一般来说不这么干,定义到@implementation里面也不行也不推荐这么干,主要现在用的是objective-c

不是。生命周期当然不会随着viewcontroller的消失而消失,也就出现了这种情况,这就是为什么不行的原因,全局变量block没有结束,所以里面的 im变量引用计数无法减一,导致了 无法释放。所以在编程的过程中最好不要这么干,很容易出问题,也给我们这些程序员提了个醒,博客很多有可能他是错的需要你去实践,去思考。基础也是非常的关键,就说这个问题其实也非常的好理解就说脑袋短路了 开始没有想到那里去,说白了还是基础功不扎实,还有就是原来压根没有那么用过。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值