一個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 操做」

相關文章
相關標籤/搜索