iOS 开发 Objective-C

iOS 底层 day09 block 捕获OC对象

2020-09-01  本文已影响0人  望穿秋水小作坊

一、block 捕获 OC对象

1. 在 ARC 环境下,编译器会根据情况自动将栈上的 block 复制到堆上,比如有以下四种情况
2. 观察下面代码,person 在断点 1 和断点 2 位置被释放了吗?
#import <Foundation/Foundation.h>
#import "Person.h"

typedef void (^SPBlock)(void);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        SPBlock block1;
        {
            Person *person1 = [[Person alloc] init];
            NSLog(@"person1,%p",person1);
            block1 = ^{
                NSLog(@"hello,%p",person1);
            };
        }
        {
            Person *person2 = [[Person alloc] init];
            NSLog(@"person2,%p",person2);
            ^{
                NSLog(@"hello,%p",person2);
            };
        }
        NSLog(@"断点1");
    }
    NSLog(@"断点2");
    return 0;
}
Demo[3570:263110] person1,0x1006acd90
Demo[3570:263110] person2,0x1006acc50
Demo[3570:263110] Person - dealloc<Person: 0x1006acc50>
Demo[3570:263110] 断点1
Demo[3570:263110] Person - dealloc<Person: 0x1006acd90>
Demo[3570:263110] 断点2
3. 观察下面代码,Person对象在断点 1 和断点 2 位置被释放了吗?
#import <Foundation/Foundation.h>
#import "Person.h"
typedef void (^SPBlock)(void);
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        SPBlock block1;
        SPBlock block2;
        {
            Person *person1 = [[Person alloc] init];
            NSLog(@"person1:%p",person1);
            block1 = ^{
                NSLog(@"hello,%p",person1);
            };
        }
        
        {
            Person *person2 = [[Person alloc] init];
            NSLog(@"person2:%p",person2);
            __weak Person *weakPerson = person2;
            block2 = ^{
                NSLog(@"hello,%p",weakPerson);
            };
        }
         NSLog(@"断点1");
    }
    NSLog(@"断点2");
    return 0;
}
Demo[4124:285733] person1:0x1005acf10
Demo[4124:285733] person2:0x1005b9c50
Demo[4124:285733] Person - dealloc<Person: 0x1005b9c50>
Demo[4124:285733] 断点1
Demo[4124:285733] Person - dealloc<Person: 0x1005acf10>
Demo[4124:285733] 断点2
4. 为了观察例子3 的本质,我们使用如下指令,将上述代码转换成 C++代码
// block1 对应结构体
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  Person *__strong person1;
};
static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
  void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
  void (*dispose)(struct __main_block_impl_0*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};

static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->person1, (void*)src->person1, 3/*BLOCK_FIELD_IS_OBJECT*/);}

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->person1, 3/*BLOCK_FIELD_IS_OBJECT*/);}

// block2 对应结构体
struct __main_block_impl_1 {
  struct __block_impl impl;
  struct __main_block_desc_1* Desc;
  Person *__weak weakPerson;
};
static struct __main_block_desc_1 {
  size_t reserved;
  size_t Block_size;
  void (*copy)(struct __main_block_impl_1*, struct __main_block_impl_1*);
  void (*dispose)(struct __main_block_impl_1*);
}
static void __main_block_copy_1(struct __main_block_impl_1*dst, struct __main_block_impl_1*src) {_Block_object_assign((void*)&dst->weakPerson, (void*)src->weakPerson, 3/*BLOCK_FIELD_IS_OBJECT*/);}

static void __main_block_dispose_1(struct __main_block_impl_1*src) {_Block_object_dispose((void*)src->weakPerson, 3/*BLOCK_FIELD_IS_OBJECT*/);}
5. 通过练习巩固上面的知识,请问下面的 Person对象多少秒后释放?
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    Person *person1 = [[Person alloc] init];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"person1:%p", person1);
    });
    
    Person *person2 = [[Person alloc] init];
    __weak Person *weakPerson2 = person2;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"weakPerson2:%p", weakPerson2);
    });
    
    
    Person *person3 = [[Person alloc] init];
    __weak Person *weakPerson3 = person3;
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"weakPerson3:%p", weakPerson3);
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"person3:%p", person3);
        });
    });
    
    NSLog(@"touchesBegan");
}
14:58:57.708776 Demo[4756:326199] touchesBegan
14:58:57.709004 Demo[4756:326199] Person - dealloc:<Person: 0x6000020ec2d0>
14:58:58.708922 Demo[4756:326199] person1:0x6000020ec2c0
14:58:58.709254 Demo[4756:326199] Person - dealloc:<Person: 0x6000020ec2c0>
14:58:59.859905 Demo[4756:326199] weakPerson2:0x0
14:58:59.860169 Demo[4756:326199] weakPerson3:0x6000020ec2e0
14:59:00.959406 Demo[4756:326199] person3:0x6000020ec2e0
14:59:00.959724 Demo[4756:326199] Person - dealloc:<Person: 0x6000020ec2e0>
上一篇 下一篇

猜你喜欢

热点阅读