乙個int變數被 block修飾與否的區別?

2021-09-17 22:43:15 字數 2296 閱讀 3110

更多:ios面試題大全

沒有修飾,被block捕獲,是值拷貝。

使用__block修飾,會生成乙個結構體,複製int的引用位址。達到修改資料。

1、block截獲自動變數(區域性變數)值對於 block 外的變數引用,block 預設是將其複製到其資料結構中來實現訪問的。也就是說block的自動變數截獲只針對block內部使用的自動變數, 不使用則不截獲, 因為截獲的自動變數會儲存於block的結構體內部, 會導致block體積變大。特別要注意的是預設情況下block只能訪問不能修改區域性變數的值。

2、 __block 修飾的外部變數

對於用 __block 修飾的外部變數引用,block 是複製其引用位址來實現訪問的。block可以修改__block 修飾的外部變數的值。

3、block的儲存域及copy操作

先來思考一下:block是儲存在棧上還是堆上呢?

其實,block有三種型別:

全域性塊存在於全域性記憶體中, 相當於單例.

棧塊存在於棧記憶體中, 超出其作用域則馬上被銷毀

堆塊存在於堆記憶體中, 是乙個帶引用計數的物件, 需要自行管理其記憶體

簡而言之,儲存在棧中的block就是棧塊、儲存在堆中的就是堆塊、既不在棧中也不在堆中的塊就是全域性塊。

遇到乙個block,我們怎麼這個block的儲存位置呢?

(1)block不訪問外界變數(包括棧中和堆中的變數)

block 既不在棧又不在堆中,在**段中,arc和mrc下都是如此。此時為全域性塊。

(2)block訪問外界變數

mrc 環境下:訪問外界變數的 block 預設儲存棧中。

arc 環境下:訪問外界變數的 block 預設儲存在堆中(實際是放在棧區,然後arc情況下自動又拷貝到堆區),自動釋放。

4、防止 block 迴圈引用

block 迴圈引用的情況:

某個類將 block 作為自己的屬性變數,然後該類在 block 的方法體裡面又使用了該類本身,如下:

self.someblock = ^(type var);
解決辦法:

(1)arc 下:使用 __weak

__weak typeof(self) weakself = self;

self.someblock = ^(type var);

(2)mrc 下:使用 __block

__block typeof(self) blockself = self;

self.someblock = ^(type var);

值得注意的是,在arc下,使用 __block 也有可能帶來的迴圈引用,如下:

// 迴圈引用 self -> _attributblock -> tmp -> self

typedef void (^block)();

@inte***ce testobj : nsobject

@end

@implementation testobj

- (id)init ;

}- (void)execblock

@end

// 使用類

id obj = [[testobj alloc] init];

[obj execblock]; // 如果不呼叫此方法,tmp 永遠不會置 nil,記憶體洩露會一直在

5、有時候我們經常也會被問到block為什麼 常使用copy關鍵字?block 使用 copy 是從 mrc遺留下來的「傳統」,在 mrc 中,方法內部的 block 是在棧區的,使用 copy 可以把它放到堆區.在 arc 中寫不寫都行:對於 block 使用 copy 還是 strong 效果是一樣的,但寫上 copy 也無傷大雅,還能時刻提醒我們:編譯器自動對 block 進行了 copy 操作。

如果不寫 copy ,該類的呼叫者有可能會忘記或者根本不知道「編譯器會自動對 block 進行了 copy 操作」

使用final 關鍵字修飾乙個變數的

使用final 關鍵字修飾乙個變數時,是引用不能變,還 是引用的物件不能變?使用final 關鍵字修飾乙個變數時,是指引用變數不能變,引用變數所指向的物件中的內容還是可以改 變的。例如,對於如下語句 final stringbuffer a new stringbuffer immutable 執行...

用乙個 int 表示 IP位址

用乙個 int 表示 ip位址。這還是08年初,面試華為時被問到的,當時也回答上來了。不過,最終 hr 也沒要我就是了 public class ip2integer else system.out.println iipv4 sb.tostring return sb.tostring conve...

乙個int型別引發的bug

今天我在專案開發中,遭遇了乙個莫名其妙的問題,概括加抽象後形成如下問題 在使用mybatis的xml語句實現dao層介面 listselectbysome param record personexample example 時候,我寫的xml中有這麼一句 if test record.id nul...