WWDC2017-- What's New in LLVM

Objective - C 可用性檢查

場(chǎng)景:
由于iOS系統(tǒng)每年都會(huì)有新的功能新的API發(fā)布,我們希望能夠把這些新API在我們的App里使用,但是你仍然要支持舊的系統(tǒng)翻翩,你不可能要求安裝你App的用戶的手機(jī)系統(tǒng)都是最新的却紧,這些新的API在舊系統(tǒng)中無(wú)法使用;
但是在iOS系統(tǒng)里支持反向配置轴合,可以設(shè)置build setting最低支持版本;
但是這樣并不安全碗短,如果你在iOS9的設(shè)備上調(diào)用了iOS11的方法受葛,你的App就很有可能會(huì)Crash或出現(xiàn)其他意外情況;
下面就來(lái)說(shuō)可用性檢查怎么幫助用戶安全配置App到舊的系統(tǒng)中偎谁?

以前的做法:
  • 查詢OC運(yùn)行時(shí)总滩,來(lái)確定API是否適用,但是這樣很容易出錯(cuò)或者忘記判斷直接執(zhí)行巡雨,如果出錯(cuò)很難測(cè)試定位問(wèn)題闰渔,而且它需要不同的語(yǔ)法來(lái)檢查每項(xiàng)全局變量、函數(shù)铐望、類(lèi)冈涧、實(shí)例方法和類(lèi)方法茂附;
  • 在Swift 2.0 已經(jīng)支持使用語(yǔ)法關(guān)鍵字#available,在運(yùn)行時(shí)查詢API的可用性督弓;編譯器在編譯時(shí)能捕捉缺失的可用性营曼,相關(guān)的可以具體到WWDC 2015 <Swift in Practice>
現(xiàn)在的做法:
  • 在iOS11中把Swift的可用性檢查引入到Objective - C
  • 如果直接調(diào)用新的API,編譯器會(huì)報(bào)如下警告:
image.png
  • 使用@available查詢API可用性愚隧,來(lái)處理警告

image.png

注:當(dāng)當(dāng)前是iOS11蒂阱,@available結(jié)構(gòu)返回值為真,這種情況下調(diào)用API很安全狂塘,如果當(dāng)前系統(tǒng)不適合蒜危,則可以在else函數(shù)處理

  • if (@available(iOS 11, *)) 在iOS11或者更新的系統(tǒng)里返回真,* 號(hào)表明在其它所有平臺(tái)上查詢?yōu)檎妫ū热鏼acOS)
  • 可用性針對(duì)新系統(tǒng)定制的一套功能很方便

應(yīng)用指定方法:在方法實(shí)現(xiàn)里無(wú)需再加@available檢查可用性睹耐,但調(diào)用該方法的人需要使用辐赞,否則會(huì)收到警告

@interface MyAlbumController : UIViewController
- (void)showFaces API_AVAILABLE(ios(11.0)); 
@end

應(yīng)用到指定類(lèi):

API_AVAILABLE(ios(11.0))
@interface MyAlbumController : UIViewController
- (void)showFaces; 
@end
C/C++的用性檢查API
  • __builtin_available
if (__builtin_available(iOS 11, macOS 10.13, *)) { 
    CFNewAPIOniOS11();
}
  • API_AVAILABLE宏需要包含<os/availability.h>
#include <os/availability.h>
// 修飾方法
void myFunctionForiOS11OrNewer(int i) API_AVAILABLE(ios(11.0), macos(10.13));

// 修飾類(lèi)
class API_AVAILABLE(ios(11.0), macos(10.13)) MyClassForiOS11OrNewer;

建議:對(duì)于現(xiàn)有項(xiàng)目,不建議直接使用新的API硝训,需要使用@available或者API_AVAILABLE檢查新API的可用性


對(duì)于查找定位bug响委,以下介紹一些Xcode的新功能,如靜態(tài)分析新功能和編譯器警告~

Analyzer 靜態(tài)分析新功能

Analyzer擅長(zhǎng)捕捉難以重現(xiàn)的極端的bug窖梁,下面介紹新加入Analyzer的三種情況:

對(duì)于 NSNumberCFNumberRef的一些錯(cuò)誤比較方式
  • 錯(cuò)誤一:NSNumber指針值直接和0比赘风,這個(gè)操作實(shí)際上是將指針值和nil相比較
@property NSNumber *photoCount; 
- (BOOL)hasPhotos {
    return self.photoCount > 0;  // X 錯(cuò)誤:不能用NSNumber直接和0比較
}
image.png
@property NSNumber *photoCount;
- (BOOL)hasPhotos {
return self.photoCount.integerValue > 0; // 正確: compare integer value to integer value
}
  • 錯(cuò)誤二:布爾運(yùn)算的隱式變換的歧義
@property NSNumber *faceCount;
- (void)identifyFaces { 
  if (self.faceCount)  // 歧義:這里`faceCount`是為nil還是0的時(shí)候return?
    return;
    // Expensive Processing
}
image.png

明確的和nil做比較!

@property NSNumber *faceCount;
- (void)identifyFaces {
    if (self.faceCount) != nil)
    return;
    // Expensive Processing
}

在Xcode設(shè)置檢查選項(xiàng):


image.png
函數(shù) dispatch_once()的使用注意

這個(gè)函數(shù)它保證這個(gè)代碼塊會(huì)被調(diào)用一次并且只有一次纵刘,常用于初始化共享全局狀態(tài)邀窃;
確保代碼塊只執(zhí)行一次,第一個(gè)參數(shù)必須是global 或則 static的變量

image.png
image.png

解決方案:使用NSLock 確保初始化只執(zhí)行一次

@implementation Album { 
NSLock *photosLock;
}
[photosLock lock];
if (self.photos == nil) { 
  self.photos = [self loadPhotos];
}
[photosLock unlock];
關(guān)于NSMutable類(lèi)的copy 屬性的檢查

定義一個(gè)可變類(lèi)型的propertycopy修飾時(shí)假哎,一般會(huì)在該屬性的Setter方法里對(duì)屬性進(jìn)行 -copy操作瞬捕,這樣會(huì)導(dǎo)致該可變類(lèi)型變成不可變類(lèi)型

會(huì)有如下問(wèn)題:

image.png

Analyzer 中的提示信息:


image.png

解決方案:在Setter方法明確的執(zhí)行 -mutableCopy,確保屬性是可變的

image.png

相關(guān)WWDC議題:Finding Bugs Using Xcode Runtime Tools

編譯器警告

Xcode9新加了100多個(gè)錯(cuò)誤和警告舵抹,來(lái)幫助我們調(diào)試和處理問(wèn)題肪虎,下面有兩個(gè)很重要的錯(cuò)誤警告:

在ARC的Block里捕獲參數(shù):

一般來(lái)說(shuō),在ARC的Block里捕獲大多數(shù)的參數(shù)都很安全

請(qǐng)找出下面代碼會(huì)出問(wèn)題的地方:

- (BOOL)validateDictionary:(NSDictionary *)dict usingChecker:(Checker *)checker error:(NSError **)error {
    __block BOOL isValid = YES;
    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
      if ([checker checkObject:obj forKey:key]) return; 
        *stop = YES;    
        isValid = NO;
      if (error) *error = [NSError errorWithDomain:...]; // 在 Block里分配參數(shù)是很不安全的
      // if (error) *error = [[[NSError errorWithDomain:...] retain] autorelease]; //默認(rèn)會(huì)加上`__autoreleasing`
    }];
    return isValid; 
}

注意:

  1. 在 Block里分配參數(shù)是很不安全的惧蛹,在ARC Block的外部參數(shù)會(huì)隱式的被加上__autoreleasing
  2. enumerateKeysAndObjectsUsingBlock這個(gè)block 內(nèi)部默認(rèn)有autoreleasepool

具體警告如下:


image.png

解決方案:使用__strong修飾輸出參數(shù)扇救,確保輸出時(shí)對(duì)象存在,沒(méi)有被銷(xiāo)毀

image.png
聲明沒(méi)有參數(shù)的方法

在iOS9香嗓,需要明確指定無(wú)參為void, 不然會(huì)報(bào)如下警告:

image.png

明確設(shè)置函數(shù)的無(wú)參void 后迅腔,對(duì)該函數(shù)傳遞參數(shù)會(huì)直接報(bào)錯(cuò):

image.png

在 Build Setting里配置:


image.png

(LTO:Link-Time Optimization)鏈接時(shí)間優(yōu)化更新

相關(guān)WWDC 2016:What's New in LLVM


相關(guān) Sessions

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市靠娱,隨后出現(xiàn)的幾起案子沧烈,更是在濱河造成了極大的恐慌,老刑警劉巖饱岸,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掺出,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡苫费,警方通過(guò)查閱死者的電腦和手機(jī)汤锨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)百框,“玉大人闲礼,你說(shuō)我怎么就攤上這事☆砦” “怎么了柬泽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嫁蛇。 經(jīng)常有香客問(wèn)我锨并,道長(zhǎng),這世上最難降的妖魔是什么睬棚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任第煮,我火速辦了婚禮,結(jié)果婚禮上抑党,老公的妹妹穿的比我還像新娘包警。我一直安慰自己,他們只是感情好底靠,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布害晦。 她就那樣靜靜地躺著,像睡著了一般暑中。 火紅的嫁衣襯著肌膚如雪壹瘟。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天鳄逾,我揣著相機(jī)與錄音俐筋,去河邊找鬼。 笑死严衬,一個(gè)胖子當(dāng)著我的面吹牛澄者,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播请琳,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼粱挡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了俄精?” 一聲冷哼從身側(cè)響起询筏,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竖慧,沒(méi)想到半個(gè)月后嫌套,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體逆屡,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年踱讨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了魏蔗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痹筛,死狀恐怖莺治,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情帚稠,我是刑警寧澤谣旁,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站滋早,受9級(jí)特大地震影響榄审,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜杆麸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一瘟判、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧角溃,春花似錦拷获、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至未蝌,卻和暖如春驮吱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背萧吠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工左冬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纸型。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓拇砰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親狰腌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子除破,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)琼腔,斷路器瑰枫,智...
    卡卡羅2017閱讀 134,693評(píng)論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件丹莲、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,117評(píng)論 4 61
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中光坝。尸诽。。 其實(shí)如果沒(méi)有APIManager這一層是沒(méi)法使用delegate的盯另,畢竟多個(gè)單...
    yhtang閱讀 5,206評(píng)論 1 23
  • 禪與 Objective-C 編程藝術(shù) (Zen and the Art of the Objective-C C...
    GrayLand閱讀 1,630評(píng)論 1 10
  • 沒(méi)有錢(qián)性含,不能生活。 沒(méi)有詩(shī)和遠(yuǎn)方土铺,如同茍且胶滋。 詩(shī)和遠(yuǎn)方召喚著我板鬓,錢(qián)在眼前氣勢(shì)洶洶悲敷。 我是一只短腿的螞蟻,遠(yuǎn)方那么遠(yuǎn)...
    又新閱讀 149評(píng)論 0 0