• OC语言(七)Block复习


    看下面一道Block的面试题:

    int i = 10;
    void(^myBlock)() = ^{
        NSLog(@"%d",i);
    };
    i = 100;
    myBlock();

    经过这个过程后,输出的i应该是10而不是100,在定义block时会将block前面的局部变量进行拷贝,后续的变量改变不会影响block内部的拷贝变量值,如果要操作block中变量的值,应该加上__block关键字。


    另外一道:

    Tip:如果在block中使用了self,block会对self强引用。

    @property (nonatomic, strong) NSMutableArray *myBlocks;
    
    int(^sum)(int,int) = ^(int x, int y){
       return [self sum:x y:y];
    }
    [self.myBlocks addObject:sum];

    注意到self对myBlocks是强引用,如果把sum加入到myBlocks数组中,myBlocks数组又会有强指针指向sum,由于sum这个block需要调用self的方法,因此sum对self是强引用,因此构成了循环引用,无法释放。


    第三道:

    如果self对象持有操作对象(例如类直接有block),而操作对象(如block)又直接访问了self,则block会对self构成强引用,self又对block强引用,会造成循环引用。

    单纯在操作对象(如block)中操作self不会造成循环引用

    例如使用线程创建block,由于非主线程默认没有消息循环(Run Loop),因此线程销毁时block也会销毁,block为线程所有,不是self所有,不会造成循环引用。

    @interface DemoObj ()
    
    @property (nonatomic, strong) NSOperationQueue *queue;
    
    @end
    
    @implementation DemoObj
    
    - (instancetype)init{
        
        if(self = [super init]){
            self.queue = [[NSOperationQueue alloc] init];
        }
        
        return self;
        
    }
    - (void)dealloc{
        
        NSLog(@"dealloc successfully");
        
    }
    
    - (void)demoOp:(id)obj{
        
        NSLog(@"%@ %@",[NSThread currentThread],obj);
        
    }
    
    - (void)demoBlockOp{
        [self.queue addOperationWithBlock:^{
            [self demoOp:@"hello"];
        }];
    }
    这种情况下,self对queue强引用,queue对block强引用,虽然block对self也有强引用,但是线程消失时block会销毁,也就不存在引用环了,因此self只有直接拥有block时才会造成循环引用。
    Tip:在这种情况下,不能使用self的弱引用(__weak Demoobj *weakself = self),这样对象会在创建时的强指针销毁时被销毁,也就是说block指向的self类不能保证其存在,故block会无法调用self,注意不能使用弱引用!!!


  • 相关阅读:
    CSS定位属性
    CSS属性
    CSS基础
    HTML
    JDBC
    语言元素
    初识Python
    redis配置文件
    zabbix
    jumpserver
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154196.html
Copyright © 2020-2023  润新知