講講你不知道的 ARC (一)

內容提要

經過閱讀本篇文章,但願您能瞭解:如何在 ARC 下,強制某個變量調用指定的方法?面試

前言

首先讓咱們先感謝以 Blaine Garst 和 Patrick Beard 爲表明的開發者。他們爲 Objective-C 這門語言添加了衆多特性,而其中最使人喜好的莫過於 ARC。優化

相信全部和我同樣經歷過手動管理內存時代的人,都會對這個特性感到很是的喜好。code

然而,有所得必有所失。本文將會講講 ARC 帶來的一些「麻煩」。orm

一道簡單的面試題

在 MRR 環境下,下面的代碼會?Compile Error / Runtime Crash / NSLog…?內存

//NSObject+Sun.h
 @interface NSObject (Sun)
 - (void)shining;
 @end

//NSObject+Sun.m
 @implementation NSObject (Sun)
 - (void)shining
 {
    NSLog(@"shining");
 }

 @end
 
//main.m
#import <Foundation/Foundation.h>

 int main(int argc, const char * argv[]) {
  @autoreleasepool {
      [NSObject shining];
}
return 0;
}

答案很簡單,雖然會產生一個警告⚠️ Class method '+shining' not found (return type defaults to 'id'),可是能夠正常輸出 shining開發

對此感到困惑的讀者能夠查看拙做 http://www.jianshu.com/p/e309...get

具體到此問題,能夠查看 @halfrost 的文章 神經病院Objective-C Runtime住院次日—消息發送與轉發編譯器

升級版面試題

剛纔的代碼在 ARC 環境下,也能正常輸出 shining 嗎?
答案是,不會。它會產生一個編譯錯誤❗️。錯誤的定義以下所示。內存管理

def err_arc_may_not_respond : Error<
  "no visible @interface for %0 declares the selector %1">;

解決方案也很簡單。在 main.m 文件中添加一行代碼便可。io

#import "NSObject+Sun.h"

問題分析

爲何在 MRR 下面可以正常運行的代碼,卻沒法在 ARC 下編譯呢?

實際上,在默認狀況下,在 ARC 下面進行編譯時,編譯器須要知道該方法是如何聲明的,只有這樣,編譯器才能自動插入相關的內存管理代碼並進行代碼優化。

那麼,是否能夠強制某個變量執行指定的方法呢?答案是:有。
能夠經過下面主動聲明的方式,告訴編譯器,請執行該方法。

[[NSObject new] performSelector:@selector(shining)];
[NSObject performSelector:@selector(shining)];

下期預告

相信不少人都沒有看明白,爲何在默認狀況下,編譯器須要知道方法是如何聲明的?

若是你知道緣由,歡迎在下方進行評論。

若是你感到好奇,敬請期待下期。

相關文章
相關標籤/搜索