iOS10 CAAnimationDelegate 的簡單適配

發表於2016-12-03

前言

最近關於適配iOS10的文章有很多,內容覆蓋的點都差不多,只是詳略差異,本文只提一個簡單的點:CAAnimationDelegate的適配,像這樣的點,iOS10中有很多,都是坑。。。

1.iOS10中CAAnimationDelegate的警告

原有的工程用xcode8開啟編譯後,莫名的增加了許多警告,其中關於動畫的警告有這樣一個,雖然執行後發現並沒有什麼影響,但還是要探究一下:

111468630-9950580a44159699
舉個?

關於警告的原因可以參考:

IOS Assigning to ‘id’ from incompatible type…解決辦法

在這裡的原因就很明瞭了,動畫的代理沒有遵循協議。
於是:

121468630-8da72afffa0039b6
接著舉?

警告消除,萬事大吉~
等下,真的就這麼萬事大吉了?把這段程式碼再用xcode7編譯一下試試。。。報錯了。。。。。。為什麼呢?
仔細想下,在iOS10之前寫動畫的協議方法,從來就沒記得要去遵循系統的動畫代理,iOS10偏偏又因為這裡給了個警告,還是先仔細對比下API吧:

131468630-73492745d08d28f1
iOS9以前的CAAnimationDelegate
141468630-5a36197f0b61a3fb
iOS10以後的CAAnimationDelegate

真的是有變化的,iOS10之前,CAAnimationDelegate只是基類的分類方法,是擴充套件,至於為什麼也要像協議方法那樣指定代理物件,應該是和其內部實現有關(只是用該指標在內部呼叫對應類的方法),需要代理物件。但在iOS10以後,CAAnimationDelegate從分類蛻變為獨立的協議方法了,所以不遵循協議,就給了警告。仔細觀察一下CAAnimationDelegatedelegate物件,它一直是一個strong型別,一般代理變數不都是weak嗎?關於這點,本人只是結合API的註釋理解為:animation是跟隨layer->view的生命週期的,需要特定的設定釋放,所以迴圈引用的問題不作考慮。
好吧,由於本人對於代理模式的理解並沒有那麼深刻,上述臆測多少是有偏差甚至是錯誤的,還望斧正。

2.iOS10中CAAnimationDelegate的適配

上面囉嗦了一堆沒有什麼“價值”的東西,還是切入主題,說說怎麼適配這個新特性吧。
關於這樣的新特性,本人用了下面的方式去進行版本適配,不知道方法算不算好,但是有效:
利用__IPHONE_OS_VERSION_MAX_ALLOWED系統巨集進行條件編譯,做法如下:

151468630-8441f916d0298f30
還是個?

這樣,在不同版本的環境下執行就做了區分,再等等……xcode7上編譯還是報錯,這段程式碼有什麼問題嗎?

有!問題在於__IPHONE_10_0這個巨集,這個巨集代表了系統版本,每次系統跟新,巨集也會對應增加新的,看下其定義:

這就是問題所在了,因為舊版本的API中,下面關於iOS10這句版本巨集定義,根本不存在,也就是說,#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0這句在xcode8之前的版本上執行,是個恆成立的條件。。。條件編譯的限制也就失去了本來的意義。。。
所以應該這麼寫就對了:

這樣做,就不會有問題了,將對應的版本號巨集直接寫成對應的數,但是這也存在一定的風險:就是__IPHONE_10_0這個巨集的具體對應值是否會因為api的又一次升級而改變,這個很難說,至少之前都是比較穩定的,只是對應增加,而沒有變化,但這畢竟是人家在維護的東西,如果直接用對應的值,在每次系統升級時,做一下檢查是十分有必要的!

161468630-1a3947683896f95b
__IPHONE_NA

所以前面提到,這樣做適配,可能並不是一個好的辦法,當然如果不嫌麻煩,反著來,多寫幾句條件編譯的邏輯,就可以避免直接用上面的巨集所對應的值,但是這意味著要考慮自己的工程相容到的最低的系統版本了,寫起來應該會很。。。

下面是與本文相關的一個簡單的Demo,有興趣的可以參考下:

Demo_Github

171468630-16bba83c14213123
Demo

如果你有更好的方式來解決這個適配的問題,歡迎在評論區留言討論。

參考文章:
1.IOS Assigning to ‘id’ from incompatible type…解決辦法
2.iOS不同版本適配問題(#ifdef __IPHONE_7_0)
3.Using SDK-Based Development
4.iOS 【關於iOS/OS X 一些廢棄API標識】

相關文章