文章标题

来源:互联网 发布:php类自调用函数 编辑:程序博客网 时间:2024/05/21 07:15

block相关,先运行下面代码,可注释相关行,查看打印结果

记住iOS内用引用计数管理内存,记住引用计数为0,释放对象内存,非0就释放不了。使用alloc new copy mutableCopy创建的对象,引用计数+1,release时,引用计数-1,记住这些话,万变不离其宗。详情请移步其他博客。

 - (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor whiteColor];    Person *p = [[Person alloc] init];    p.name = @"jack";    p.address = @"BeiJing";    __weak typeof(p) weakP = p;    p.callBack = ^(){        __strong typeof(weakP) stongP = weakP;// 可注释//         __strong typeof(stongP) sstongP = stongP;// 可注释        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{             NSLog(@"--%@",stongP.name);        });    };    p.callBack();} - (void)test{    Person *p = [[Person alloc] init];    p.name = @"rose";    __weak typeof(p) wp = p;// 可注释,再次查看运行结果    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        NSLog(@"%@",wp.name);    });}
  • 在ARC默认情况下,Block的内存存储在堆中,ARC会自动进行内存管理,程序员只需要避免循环引用即可
  • 在Block的内存存储在堆中时,如果在Block中引用了外面的对象,会对所引用的对象进行强引用,但是在Block被释放时会自动去掉对该对象的强引用,所以不会造成内存泄漏
  • 如果对象内部有一个Block属性,而在Block内部又访问了该对象,那么会造成循环引用
  • MRC环境下,默认保存在栈内
  • 如果在Block中引用了外面的对象,不会对所引用的对象进行任何操作
  • 如果对Block进行一次copy操作,那么Block的内存会被移动到堆中,这时需要开发人员对其进行release操作来管理内存
  • 如果对Block进行一次copy操作,那么Block的内存会被移动到堆中,在Block的内存存储在堆中时,如果在Block中引用了外面的对象,会对所引用的对象进行一次retain操作,即使在Block自身调用了release操作之后,Block也不会对所引用的对象进行一次release操作,这时会造成内存泄漏
  • 如果对Block进行一次copy操作,那么Block的内存会被移动到堆中,在Block的内存存储在堆中时,如果在Block中引用了外面的对象,会对所引用的对象进行一次retain操作,为了不对所引用的对象进行一次retain操作,可以在对象的前面使用下划线下划线block来修饰

分析 test方法

  • 如果是以下这样, test方法走完,p即释放打印结果
  • - (void)test
    {
    Person *p = [[Person alloc] init];
    p.name = @"rose";
    NSLog(@"%@",p.name);
    }
  • 如果是以下这样, test方法走完,p没有立即释放,因为被下面block强引用,必须要等block走完,p才能释放,打印结果
  • - (void)test
    {
    Person *p = [[Person alloc] init];
    p.name = @"rose";
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    NSLog(@"%@",p.name);
    });
    }
  • 如果是以下这样, test方法走完,p立即释放,因为block弱引用,引用计数为0这里写图片描述
  • (void)test
    {
    Person *p = [[Person alloc] init];
    p.name = @”rose”;
    __weak typeof(p) wp = p;// 可注释,再次查看运行结果
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    NSLog(@”%@”,wp.name);
    });
    }
    `