OC中block為什么用copy修飾

在 Objective-C 中硼瓣,block 是一種匿名函數(shù),可以捕獲上下文中的變量末患。為了確保 block 在內(nèi)存管理中的正確性牲证,通常使用 copy 修飾符哮针。以下是詳細(xì)原因和解釋:


1. block 的內(nèi)存管理

  • block 的類型
    • NSGlobalBlock:存儲(chǔ)在全局區(qū),不捕獲任何外部變量坦袍。
    • NSStackBlock:存儲(chǔ)在棧區(qū)诚撵,捕獲外部變量。
    • NSMallocBlock:存儲(chǔ)在堆區(qū)键闺,由棧區(qū) block 復(fù)制而來(lái)。
  • 默認(rèn)行為
    • 當(dāng) block 捕獲外部變量時(shí)澈驼,默認(rèn)是 NSStackBlock辛燥,存儲(chǔ)在棧區(qū)。
    • 棧區(qū)的 block 在作用域結(jié)束后會(huì)被釋放缝其,如果此時(shí)嘗試訪問該 block挎塌,會(huì)導(dǎo)致崩潰。

2. 為什么用 copy 修飾

  • 將 block 從棧復(fù)制到堆
    • 使用 copy 修飾符可以將 NSStackBlock 復(fù)制為 NSMallocBlock内边,存儲(chǔ)在堆區(qū)榴都。
    • 堆區(qū)的 block 生命周期由引用計(jì)數(shù)管理,可以安全地在作用域外使用漠其。
  • 避免野指針
    • 如果不使用 copy嘴高,棧區(qū)的 block 在作用域結(jié)束后會(huì)被釋放竿音,后續(xù)訪問會(huì)導(dǎo)致野指針問題。
  • ARC 下的行為
    • 在 ARC(自動(dòng)引用計(jì)數(shù))環(huán)境下拴驮,copy 是默認(rèn)行為春瞬,即使不顯式使用 copy,編譯器也會(huì)自動(dòng)將 block 復(fù)制到堆區(qū)套啤。
    • 但在 MRC(手動(dòng)引用計(jì)數(shù))環(huán)境下宽气,必須顯式使用 copy

3. 代碼示例

  • MRC 環(huán)境下
    typedef void (^MyBlock)(void);
    
    @interface MyClass : NSObject
    @property (nonatomic, copy) MyBlock block;
    @end
    
    @implementation MyClass
    - (void)setupBlock {
        int value = 10;
        self.block = [^{
            NSLog(@"Value: %d", value);
        } copy]; // 必須使用 copy
    }
    @end
    
  • ARC 環(huán)境下
    @interface MyClass : NSObject
    @property (nonatomic, copy) MyBlock block;
    @end
    
    @implementation MyClass
    - (void)setupBlock {
        int value = 10;
        self.block = ^{
            NSLog(@"Value: %d", value);
        }; // ARC 下會(huì)自動(dòng) copy
    }
    @end
    

4. 注意事項(xiàng)

  • 循環(huán)引用
    • 使用 copy 修飾 block 時(shí)潜沦,如果 block 捕獲了 self萄涯,可能導(dǎo)致循環(huán)引用。
    • 解決方法:使用 __weak 弱引用打破循環(huán)唆鸡。
      __weak typeof(self) weakSelf = self;
      self.block = ^{
          __strong typeof(weakSelf) strongSelf = weakSelf;
          [strongSelf doSomething];
      };
      
  • 性能影響
    • copy 操作會(huì)涉及內(nèi)存分配和復(fù)制涝影,可能對(duì)性能有輕微影響。
    • 但對(duì)于大多數(shù)場(chǎng)景喇闸,這種影響可以忽略袄琳。

5. 總結(jié)

  • 在 Objective-C 中,使用 copy 修飾 block 是為了將 block 從棧區(qū)復(fù)制到堆區(qū)燃乍,確保其生命周期和內(nèi)存安全唆樊。
  • 在 MRC 環(huán)境下必須顯式使用 copy,而在 ARC 環(huán)境下編譯器會(huì)自動(dòng)處理刻蟹。
  • 使用 copy 時(shí)需注意循環(huán)引用問題逗旁,可以通過弱引用解決。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舆瘪,一起剝皮案震驚了整個(gè)濱河市片效,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌英古,老刑警劉巖淀衣,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異召调,居然都是意外死亡膨桥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門唠叛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)只嚣,“玉大人,你說我怎么就攤上這事艺沼〔嵛瑁” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵障般,是天一觀的道長(zhǎng)调鲸。 經(jīng)常有香客問我盛杰,道長(zhǎng),這世上最難降的妖魔是什么线得? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任饶唤,我火速辦了婚禮,結(jié)果婚禮上贯钩,老公的妹妹穿的比我還像新娘募狂。我一直安慰自己,他們只是感情好角雷,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布祸穷。 她就那樣靜靜地躺著,像睡著了一般勺三。 火紅的嫁衣襯著肌膚如雪雷滚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天吗坚,我揣著相機(jī)與錄音祈远,去河邊找鬼。 笑死商源,一個(gè)胖子當(dāng)著我的面吹牛车份,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牡彻,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼扫沼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了庄吼?” 一聲冷哼從身側(cè)響起缎除,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎总寻,沒想到半個(gè)月后器罐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渐行,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年轰坊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殊轴。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖袒炉,靈堂內(nèi)的尸體忽然破棺而出旁理,到底是詐尸還是另有隱情,我是刑警寧澤我磁,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布孽文,位于F島的核電站驻襟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏芋哭。R本人自食惡果不足惜沉衣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望减牺。 院中可真熱鬧豌习,春花似錦、人聲如沸拔疚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)稚失。三九已至栋艳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間句各,已是汗流浹背吸占。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凿宾,地道東北人矾屯。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像菌湃,于是被迫代替她去往敵國(guó)和親问拘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容