一个int变量被__block修饰与否的区别?

更多:iOS面试题大全面试

没有修饰,被block捕获,是值拷贝。
使用__block修饰,会生成一个结构体,复制int的引用地址。达到修改数据。

一、block截获自动变量(局部变量)值数据结构

对于 block 外的变量引用,block 默认是将其复制到其数据结构中来实现访问的。也就是说block的自动变量截获只针对block内部使用的自动变量, 不使用则不截获, 由于截获的自动变量会存储于block的结构体内部, 会致使block体积变大。特别要注意的是默认状况下block只能访问不能修改局部变量的值。spa

二、 __block 修饰的外部变量code

对于用 __block 修饰的外部变量引用,block 是复制其引用地址来实现访问的。block能够修改__block 修饰的外部变量的值。对象

三、Block的存储域及copy操做内存

先来思考一下:Block是存储在栈上仍是堆上呢?
其实,block有三种类型:作用域

  • 全局块(_NSConcreteGlobalBlock)
  • 栈块(_NSConcreteStackBlock)
  • 堆块(_NSConcreteMallocBlock)

全局块存在于全局内存中, 至关于单例.
栈块存在于栈内存中, 超出其做用域则立刻被销毁
堆块存在于堆内存中, 是一个带引用计数的对象, 须要自行管理其内存
简而言之,存储在栈中的Block就是栈块、存储在堆中的就是堆块、既不在栈中也不在堆中的块就是全局块。rem

遇到一个Block,咱们怎么这个Block的存储位置呢?get

(1)Block不访问外界变量(包括栈中和堆中的变量)编译器

Block 既不在栈又不在堆中,在代码段中,ARC和MRC下都是如此。此时为全局块。

(2)Block访问外界变量

MRC 环境下:访问外界变量的 Block 默认存储栈中。
ARC 环境下:访问外界变量的 Block 默认存储在堆中(实际是放在栈区,而后ARC状况下自动又拷贝到堆区),自动释放。

四、防止 Block 循环引用
Block 循环引用的状况:
某个类将 block 做为本身的属性变量,而后该类在 block 的方法体里面又使用了该类自己,以下:

self.someBlock = ^(Type var){
    [self dosomething];
};

解决办法:

(1)ARC 下:使用 __weak

__weak typeof(self) weakSelf = self;
self.someBlock = ^(Type var){
   [weakSelf dosomething];
};

(2)MRC 下:使用 __block

__block typeof(self) blockSelf = self;
self.someBlock = ^(Type var){
   [blockSelf dosomething];
};

值得注意的是,在ARC下,使用 __block 也有可能带来的循环引用,以下:

// 循环引用 self -> _attributBlock -> tmp -> self
typedef void (^Block)();
@interface TestObj : NSObject
{
    Block _attributBlock;
}
@end

@implementation TestObj
- (id)init {
    self = [super init];
    __block id tmp = self;
    self.attributBlock = ^{
        NSLog(@"Self = %@",tmp);
        tmp = nil;
   };
}

- (void)execBlock {
    self.attributBlock();
}
@end

// 使用类
id obj = [[TestObj alloc] init];
[obj execBlock]; // 若是不调用此方法,tmp 永远不会置 nil,内存泄露会一直在

五、有时候咱们常常也会被问到block为何 常使用copy关键字?

block 使用 copy 是从 MRC遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 能够把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 仍是 strong 效果是同样的,但写上 copy 也无伤大雅,还能时刻提醒咱们:编译器自动对 block 进行了 copy 操做。若是不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操做”

相关文章
相关标签/搜索