歷代iOS版本 — iOS9

一. SDK

1. 限制HTTP協(xié)議,全部改用更安全的HTTPS

iOS9讓所有的HTTP默認(rèn)使用了HTTPS遭殉,原來的HTTP協(xié)議傳輸都改成TLS1.2協(xié)議進(jìn)行傳輸图柏。直接造成的情況就是App發(fā)請求的時(shí)候彈出網(wǎng)絡(luò)無法連接镜豹。

對于這個(gè)問題的解決方案,網(wǎng)上有一篇博客已經(jīng)總結(jié)的很好了,我在這就簡要的說明怎么處理這種問題.

HTTPS和HTTP的區(qū)別在于哪里呢?

舉個(gè)簡單的栗子:原來的 HTTP 是塑料水管,容易被戳破;那么如今新設(shè)計(jì)的 HTTPS 就像是在原有的塑料水管之外,

再包一層金屬水管飘千。一來,原有的塑料水管照樣運(yùn)行栈雳;二來护奈,用金屬加固了之后,不容易被戳破哥纫。

Apple讓你的HTTP采用SSL/TLS協(xié)議霉旗,就是讓你從HTTP轉(zhuǎn)到HTTPS.

不使用SSL/TLS的HTTP通信,就是不加密的通信蛀骇!

所有信息明文傳播厌秒,帶來了三大風(fēng)險(xiǎn):

竊聽風(fēng)險(xiǎn)(eavesdropping):第三方可以獲知通信內(nèi)容。

篡改風(fēng)險(xiǎn)(tampering):第三方可以修改通信內(nèi)容擅憔。

冒充風(fēng)險(xiǎn)(pretending):第三方可以冒充他人身份參與通信鸵闪。

SSL/TLS協(xié)議是為了解決這三大風(fēng)險(xiǎn)而設(shè)計(jì)的:

所有信息都是加密傳播,第三方無法竊聽雕欺。

具有校驗(yàn)機(jī)制岛马,一旦被篡改棉姐,通信雙方會(huì)立刻發(fā)現(xiàn)屠列。

配備身份證書,防止身份被冒充伞矩。

  • 在 Info.plist 中聲明笛洛,倒退回不安全的網(wǎng)絡(luò)請求依然能讓App訪問指定http,甚至任意的http(蘋果不建議這么做):
image.png

需要添加的節(jié)點(diǎn)

http://blog.csdn.net/aa2397199142/article/details/48915377
參考 :http://www.cnblogs.com/endtel/p/4810042.html

NSAppTransportSecurity - NSAllowsArbitraryLoads

這個(gè)子節(jié)點(diǎn)的意思是:是否仍然允許加載

設(shè)為YES的話就將禁用了AppTransportSecurity轉(zhuǎn)而使用用戶自定義的設(shè)置乃坤,這個(gè)問題就解決了苛让。

2. Bitcode

bitcode 是被編譯程序的一種中間形式的代碼沟蔑。包含 bitcode 配置的程序?qū)?huì)在 App Store 上被編譯和鏈接。 bitcode 允許蘋果在后期重新優(yōu)化我們程序的二進(jìn)制文件狱杰,而不需要我們重新提交一個(gè)新的版本到 App Store 上瘦材。

當(dāng)我們提交程序到 App Store上時(shí), Xcode 會(huì)將程序編譯為一個(gè)中間表現(xiàn)形式( bitcode )仿畸。然后 App store 會(huì)再將這個(gè) bitcode 編譯為可執(zhí)行的64位或32位程序食棕。

  1. Xcode 7默認(rèn)開啟 Bitcode ,如果應(yīng)用開啟 Bitcode错沽,那么其集成的其他第三方庫也需要是 Bitcode 編譯的包才能真正進(jìn)行 Bitcode 編譯

  2. 開啟 Bitcode 編譯后簿晓,編譯產(chǎn)生的 .app 體積會(huì)變大(中間代碼,不是用戶下載的包)千埃,且 .dSYM 文件不能用來崩潰日志的符號化(用戶下載的包是 Apple 服務(wù)重新編譯產(chǎn)生的憔儿,有產(chǎn)生新的符號文件)

  3. 通過 Archive 方式上傳 AppStore 的包,可以在Xcode的Organizer工具中下載對應(yīng)安裝包的新的符號文件

iOS 9 中終于可以僅選擇需要的內(nèi)容 (Slicing) 下載了放可。

這對用戶來說是很大的利好谒臼,因?yàn)橹恍枰壍?iOS 9,就可以節(jié)省很多流量吴侦。對于開發(fā)者來說屋休,并沒有太多要做的事情,只需要使用 asset catalog 來管理素材標(biāo)記 2x 3x 就可以了备韧。

給 App 瘦身的另一個(gè)手段是提交 Bitcode 給 Apple劫樟,而不是最終的二進(jìn)制。Bitcode 是 LLVM 的中間碼织堂,在編譯器更新時(shí)叠艳,Apple 可以用你之前提交的 Bitcode 進(jìn)行優(yōu)化,這樣你就不必在編譯器更新后再次提交你的 app易阳,也能享受到編譯器改進(jìn)所帶來的好處附较。Bitcode 支持在新項(xiàng)目中是默認(rèn)開啟的,沒有特別理由的話潦俺,你也不需要將它特意關(guān)掉拒课。

應(yīng)該有朋友在真機(jī)調(diào)試的時(shí)候發(fā)現(xiàn)在使用微博微信等第三方SDK的時(shí)候,會(huì)提示報(bào)錯(cuò),

XXXX’ does not contain bitcode. You must rebuild it with bitcode enabled

(Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor,

or disable bitcode for this target. for architecture arm64

Xcode默認(rèn)開啟bitcode模式,bitcode的理解應(yīng)該是把程序編譯成的一種過渡代碼,然后蘋果再把這個(gè)過渡代碼編譯成可執(zhí)行的程序事示。bitcode也允許蘋果在后期重新優(yōu)化我們程序的二進(jìn)制文件早像,可以直接理解為App瘦身。

解決方式:

  1. 某些第三方庫還不支持bitcode,我們只能等待庫的開發(fā)者升級了此項(xiàng)功能.(這個(gè)是我們所不能掌握的,嘿嘿)

  2. 直接禁用bitcode,禁用的方法就是找到如下配置肖爵,選為NO.注意:iOS中bitcode是默認(rèn)YES卢鹦,watchOS中bitcodes是不讓改的必須為YES。

image.png
  1. 選為NO禁用

3. 企業(yè)級分發(fā)

在iOS8只是彈出一個(gè)窗問你是否需要讓手機(jī)信任這個(gè)應(yīng)用劝堪,但是在iOS9卻直接禁止冀自,如果真的想信任需要自己去手動(dòng)開啟揉稚。類似于Mac系統(tǒng)從未知開發(fā)者處下載的dmg直接打不開,然后要到系統(tǒng)偏好設(shè)置的安全性與隱私手動(dòng)打開熬粗。

解決方式:

  • 設(shè)置-->通用--->描述文件 自行添加信任.

選擇描述文件

添加信任

這個(gè)跟著找一下就找到了搀玖。

  1. URL scheme 引入白名單概念

URL scheme一般使用的場景是應(yīng)用程序有分享或跳其他平臺(tái)授權(quán)的功能,分享或授權(quán)后再跳回來.

在iOS8并沒有做過多限制驻呐,但是iOS9需要將你要在外部調(diào)用的URL scheme列為白名單巷怜,才可以完成跳轉(zhuǎn).

如果iOS9沒做適配 會(huì)報(bào)如下錯(cuò)誤 :

canOpenURL: failed for URL : "mqzone://qqapp" - error: "This app is not allowed to query for scheme mqzone"

例如在實(shí)現(xiàn)第三方登錄時(shí),不能直接跳轉(zhuǎn)到相應(yīng)的app直接獲取權(quán)限.

解決方式為:

  • 設(shè)置應(yīng)用白名單 否則不能直接關(guān)聯(lián)上你手機(jī)里的應(yīng)用

    在info.plist中加入

    <key>LSApplicationQueriesSchemes</key> <array>

    <string>wechat</string>

    <string>weixin</string>

    <string>sinaweibohd</string>

    <string>sinaweibo</string>

    <string>sinaweibosso</string>

    <string>weibosdk</string>

    <string>weibosdk2.5</string>

    <string>mqqapi</string>

    <string>mqq</string>

    <string>mqqOpensdkSSoLogin</string>

    <string>mqqconnect</string>

    <string>mqqopensdkdataline</string>

    <string>mqqopensdkgrouptribeshare</string>

    <string>mqqopensdkfriend</string>

    <string>mqqopensdkapi</string>

    <string>mqqopensdkapiV2</string>

    <string>mqqopensdkapiV3</string>

    <string>mqzoneopensdk</string>

    <string>wtloginmqq</string>

    <string>wtloginmqq2</string>

    <string>mqqwpa</string>

    <string>mqzone</string>

    <string>mqzonev2</string>

    <string>mqzoneshare</string>

    <string>wtloginqzone</string>

    <string>mqzonewx</string>

    <string>mqzoneopensdkapiV2</string>

    <string>mqzoneopensdkapi19</string>

    <string>mqzoneopensdkapi</string>

    <string>mqzoneopensdk</string>

    <string>alipay</string>

    <string>alipayshare</string></array>

  1. statusBar

以前我們?yōu)榱四軌驅(qū)崟r(shí)的控制頂部statusbar的樣式,可能會(huì)在喜歡使用

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]

[[UIApplication sharedApplication]setStatusBarHidden:YES];

但是這么做之前需要將 info.plist 里面加上View controller-based status bar appearance BOOL值設(shè)為NO暴氏,就是把控制器控制狀態(tài)欄的權(quán)限給禁了延塑,用UIApplication來控制。

但是這種做法在iOS9不建議使用了答渔,建議我們使用把那個(gè)BOOL值設(shè)為YES关带,然后用控制器的方法來管理狀態(tài)欄比如。

  • (UIStatusBarStyle)preferredStatusBarStyle

{

return UIStatusBarStyleLightContent;

}

6. 字體

iOS9中沼撕,中文系統(tǒng)字體變?yōu)榱藢橹袊O(shè)計(jì)的“蘋方”,字體有輕微的加粗效果宋雏,并且最關(guān)鍵的是字體間隙變大了!

所以很多原本寫死了width的label可能會(huì)出現(xiàn)“...”的情況务豺。

包括在很多時(shí)候我們自動(dòng)計(jì)算行高行寬的時(shí)候出現(xiàn)偏差,導(dǎo)致一些不可知的錯(cuò)誤

解決方式:

// 字體的大小

CGSize size = [title sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14.0f]}];

CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));

加上向上取整 ceilf()就能解決了.

7. AFNetworking

為了迎合iOS新版本的升級, AFNetworking在3.0版本中刪除了基于 NSURLConnection API的所有支持磨总。

如果你的項(xiàng)目以前使用過這些API,建議立即升級到基于 NSURLSession 的API的AFNetworking的版本笼沥。

8.AVKit

使用 AVPlayerViewController 或者 AVPlayerLayer 來播放視頻蚪燕。但如果你之前選擇的方案是 MPMoviePlayerController 或者 MPMoviePlayerViewController 的話,你可能也需要盡早遷移到 AVKit 的框架下來奔浅,因?yàn)?Media Player 將在 iOS 9 被標(biāo)記為 deprecated 并不再繼續(xù)維護(hù)馆纳。

9.UI Test

在開發(fā)領(lǐng)域里,測試一直是保障產(chǎn)品質(zhì)量關(guān)鍵汹桦。從 Xcode 4 以來鲁驶,測試在 app 開發(fā)中的地位可謂是逐年上升。從 XCT 框架的引入舞骆,到測試 target 成為新建項(xiàng)目時(shí)的默認(rèn)钥弯,再到去年加入的異步代碼測試和性能測試《角荩可以說現(xiàn)在 Xcode 自帶的測試框架已經(jīng)能滿足絕大部分單元測試的需求了脆霎。

但是這并不夠。開發(fā)一個(gè) iOS app 從來都是更注重 UI 和用戶體驗(yàn)的工作赂蠢,而簡單地單元測試可以很容易地保證 model 層的正確绪穆,卻很難在 UI 方面有所作為辨泳。如何為一個(gè) app 編寫 UI 測試一直是 Cocoa 社區(qū)的難題之一虱岂。之前的話有像是 KIF玖院,Automating,甚至是 FBSnapshotTestCase 這種腦洞大開的方案第岖。今年 Apple 給出了一個(gè)更加誘人的選項(xiàng)难菌,那就是 Xcode 自帶的 XCUITest 的一系列工具。

和大部分已有的 UI 測試工具類似蔑滓,XCUI 使用 Accessibility 標(biāo)記來確定 view郊酒,但因?yàn)槭?Apple 自家的東西,它可以自動(dòng)記錄你的操作流程键袱,所以你只需要書寫最后的驗(yàn)證部分就可以了燎窘,比其他的 UI 測試工具方便很多

10 . Swift 2

Swift 2 里主要的改動(dòng)是錯(cuò)誤處理方面的變化,Apple 從 Cocoa 傳統(tǒng)的基于 NSError 錯(cuò)誤處理方式變?yōu)榱?throw catch 的異常處理機(jī)制蹄咖。這個(gè)轉(zhuǎn)變確實(shí)可以讓程序更加安全褐健,新增的 ErrorType 也很好地將錯(cuò)誤描述進(jìn)行了統(tǒng)一。但是在實(shí)際接觸了一兩天之后澜汤,在語法上感覺要比原來的處理寫的代碼多一些蚜迅。可能是長久以來使用 NSError 的習(xí)慣導(dǎo)致吧俊抵,筆者還并沒有能很好地全面接受 Swift 2 中的異常機(jī)制谁不。不過這次 Apple 做的相對激進(jìn),把 Cocoa API 中的 error 全數(shù)替換成了 throw徽诲。所以不管情不情愿刹帕,轉(zhuǎn)型到異常處理是 Swift 開發(fā)者必須面對的了。

另外 Apple 新加了一些像是 guard 和 defer 這樣的控制流關(guān)鍵字谎替,這在其他一些語言里也是很實(shí)用的特性轩拨,這讓 Swift 的書寫更加簡化,閱讀起來更流暢院喜。為了解決在運(yùn)行時(shí)的不同 SDK 的可用性的問題亡蓉,Apple 還在 Swift 2 里加入了 avaliable 塊,以前我們需要自己去記憶 API 的可用性喷舀,并通過檢查系統(tǒng)版本并進(jìn)行對比來做這件事情】潮簦現(xiàn)在有了 avaliable 檢測,編譯器將會(huì)檢查出那些可能出現(xiàn)版本不匹配的 API 調(diào)用硫麻,app 開發(fā)的安全性得到了進(jìn)一步的保障爸邢。為了讓整個(gè) SDK 更適合 Swift 的語法習(xí)慣,Apple 終于在 Objective-C 中引入了泛型拿愧。這看似是 Objective-C 的加強(qiáng)杠河,但是實(shí)際上卻實(shí)實(shí)在在地是為 Swift 一統(tǒng) Apple 開發(fā)開路。有了 Objective-C 泛型以后,用 Swift 訪問 Cocoa API 基本不會(huì)再得到 AnyObject 類型了券敌,這使得 Swift 的安全特性又上了一層臺(tái)階唾戚。

11 .iOS9 下使用 Masonry 會(huì)引起崩潰的一種情況

我們在使用時(shí)候一直將 leading 與 left 劃為等號,這樣做在 iOS8(及以前)上是正常的待诅,但在 iOS9 上這樣的觀念可能會(huì)引起崩潰叹坦,比如:

make.left.equalTo(self.mas_leading).offset(15);

應(yīng)該為:

make.left.equalTo(self.mas_left).offset(15);

同理 mas_training 也需要改為right

12 .navigationController狀態(tài)欄樣式新的設(shè)置方法

如果你按照上面的方法設(shè)置了,但還是不行卑雁。八成是 rootViewController 設(shè)置的問題募书,你必須設(shè)置 rootViewController,編譯器才會(huì)去 rootViewController 中重載 preferredStatusBarStyle 方法测蹲。

另外當(dāng)你在 appdelegate 中將 navigationController 設(shè)為 rootViewController 的時(shí)候:

self.window.rootViewController = self.navigationController;

因?yàn)?rootViewController 變?yōu)榱?navigationController莹捡,你在 ViewController 里重寫 preferredStatusBarStyle 方法是不會(huì)起作用的。所以最好的方法是

  • (void)viewDidLoad

{

[super viewDidLoad];

self.title = @"微博@iOS程序犭袁";

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;

}

如果你還是想重寫 preferredStatusBarStyle 方法來達(dá)到作用扣甲,那最好使用分類來解決:

.h文件:

//

// UINavigationController+StatusBarStyle.h

// 微博@iOS程序犭袁

//

// Created by https://github.com/ChenYilong/iOS9AdaptationTips/ on 15/6/8.

// Copyright (c) 2015年 http://weibo.com/luohanchenyilong/ . All rights reserved.

//

import <UIKit/UIKit.h>

@interface UINavigationController (StatusBarStyle)

@end

.m文件:

//

// UINavigationController+StatusBarStyle.m

// 微博@iOS程序犭袁

//

// Created by https://github.com/ChenYilong/iOS9AdaptationTips/ on 15/6/8.

// Copyright (c) 2015年 http://weibo.com/luohanchenyilong/ . All rights reserved.

//

import "UINavigationController+StatusBarStyle.h"

@implementation UINavigationController (StatusBarStyle)

  • (UIStatusBarStyle)preferredStatusBarStyle

{

//also you may add any fancy condition-based code here

return UIStatusBarStyleLightContent;

}

@end

我在倉庫里給出了 navigation 的設(shè)置方法道盏,見Demo4。

參考鏈接: preferredStatusBarStyle isn't called--For anyone using a UINavigationController:

13.使用了 HTML 的 iframe 元素可能導(dǎo)致無法從 Safari 跳轉(zhuǎn)至 App

我們都知道文捶,從網(wǎng)易新聞分享一條新聞到QQ荷逞,然后從QQ中打開鏈接再用safari打開鏈接,在iOS8上粹排,這個(gè)時(shí)候會(huì)跳轉(zhuǎn)到網(wǎng)易新聞App种远。但是現(xiàn)在 (2015年09月23日)版本的網(wǎng)易新聞在 iOS9 就不能正常跳轉(zhuǎn),會(huì)跳轉(zhuǎn)到 App Store 頁面并提示要不要打開 App Store顽耳。

這是很可能是因?yàn)槭褂昧?HTML 的 iframe 元素坠敷,并將自定義的鏈接放進(jìn)了該元素中

舉例說明:

我之前寫的一個(gè) Demo: 模仿 《簡書 App》 的效果:在html中跳轉(zhuǎn)到App中的對應(yīng)頁面,并能從App跳轉(zhuǎn)到原來的網(wǎng)址,在例子中直接調(diào)用自定義鏈接在 iOS9上是可以跳轉(zhuǎn)到 App 中的射富,然而膝迎,如果用 iframe 元素包起來就會(huì)變不可用。

參考鏈接:

  1. HTML 的iframe 標(biāo)簽

  2. iOS 9 safari iframe src with custom url scheme not working

14.在didFinishLaunchingWithOptions結(jié)束后還沒有設(shè)置window的rootViewController會(huì)導(dǎo)致崩潰

iOS9 不允許在 didFinishLaunchingWithOptions 結(jié)束了之后胰耗,還沒有設(shè)置 window 的rootViewController 限次。 也許是 Xcode7 的編譯器本身就不支持。

崩潰時(shí)的控制臺(tái)日志提示:

*** Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m:3294

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'

*** First throw call stack:

/省略/

libc++abi.dylib: terminating with uncaught exception of type NSException

(lldb)

解決的方法是先設(shè)初始化個(gè)值柴灯,之后再賦值替換掉:

UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreenmainScreen].bounds];

window.rootViewController = [[UIViewController alloc] init];

尤其注意一種情況卖漫,在 iOS8以前,我們有時(shí)候會(huì)通過在 AppDelegate 中添加另一個(gè) UIWindow 赠群,并修改其 Level 來達(dá)到 addSubview 的效果羊始,因而也不設(shè)置 window 的 rootViewController ,而是把它直接以視圖的形式展示了查描,則在 iOS8 上是警告突委,在 iOS9 上就崩潰了柏卤。

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

self.window.backgroundColor = [UIColor yellowColor];

[self.window makeKeyAndVisible];

UIWindow *normalWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

normalWindow.backgroundColor = [UIColor blueColor];

normalWindow.windowLevel = UIWindowLevelAlert;

[normalWindow makeKeyAndVisible];

return YES;

}

這種情況,在 didFinishLaunchingWithOptions 需要修改原來的策略匀油,將第二個(gè) window 類型改為其他類型缘缚,比如 viewController 類型、navigation 類型钧唐、tabbarController 類型等

Xcode 7+

·泛型

     因?yàn)镾wift中集合的元素都是有類型的, 為了和Swift更好的兼容, 新版本里, OC開始支持泛型, 主要是在各種集合類型(比如數(shù)組, 集合, 字典)中使用.

這無疑是本次最重大的改進(jìn),有了泛型后終于可以指定容器類中對象的類型了:

<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
|

1

2

|

NSArray<NSString *> *strings = @[@"sun", @"yuan"];

NSDictionary<NSString *, NSNumber *> *mapping = @{@"a": @1, @"b": @2};

|

返回值的 id 被替換成具體的類型后匠襟,令人感動(dòng)的代碼提示也出來了:

假如向泛型容器中加入錯(cuò)誤的對象钝侠,編譯器會(huì)不開心的:

image.jpeg

系統(tǒng)中常用的一系列容器類型都增加了泛型支持,甚至連 NSEnumerator 都支持了酸舍,這是非常 Nice 的改進(jìn)帅韧。和 Nullability 一樣,我認(rèn)為最大的意義還是豐富了接口描述信息啃勉,對比下面兩種寫法:

<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
|

1

2

|

@property (readonly) NSArray *imageURLs;

@property (readonly) NSArray<NSURL *> *imageURLs;

|

不用多想就清楚下面的數(shù)組中存的是什么忽舟,避免了 NSString 和 NSURL 的混亂淮阐。

(自定義泛型類)

      比起使用系統(tǒng)的泛型容器叮阅,更好玩的是自定義一個(gè)泛型類勒叠,目前這里還沒什么文檔,但攔不住我們寫[測試](http://lib.csdn.net/base/softwaretest "軟件測試知識庫")代碼比驻,假設(shè)我們要自定義一個(gè) Stack 容器類:

<colgroup><col style="width: 34px;"><col style="width: 523px;"></colgroup>
|

1

2

3

4

5

|

@interface Stack<ObjectType> : NSObject

  • (void)pushObject:(ObjectType)object;

  • (ObjectType)popObject;

@property (nonatomic, readonly) NSArray<ObjectType> *allObjects;

@end

|
| | |

      這個(gè) ObjectType 是傳入類型的 placeholder,它只能在 @interface 上定義(類聲明蹭秋、類擴(kuò)展扰付、Category),如果你喜歡用 T 表示也 ok仁讨,這個(gè)類型在 @interface 和 @end 區(qū)間的作用域有效羽莺,可以把它作為入?yún)ⅰ⒊鰠⒍椿怼⑸踔羶?nèi)               部 NSArray 屬性的泛型類型盐固,應(yīng)該說一切都是符合預(yù)期的。我們還可以給 ObjectType 增加類型限制丈挟,比如:

<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
|

1

2

3

4

|

// 只接受 NSNumber * 的泛型

@interface Stack<ObjectType: NSNumber *> : NSObject

// 只接受滿足 NSCopying 協(xié)議的泛型

@interface Stack<ObjectType: id<NSCopying>> : NSObject

|

若什么都不加刁卜,表示接受任意類型 ( id );當(dāng)類型不滿足時(shí)編譯器將產(chǎn)生 error曙咽。

實(shí)例化一個(gè) Stack长酗,一切工作正常:

image.jpeg

對于多參數(shù)的泛型,用逗號隔開桐绒,其他都一樣夺脾,可以參考 NSDictionary 的頭文件。

  • 可空性標(biāo)注

    因?yàn)镾wift的代碼里面的主要類型默認(rèn)是沒有空值一說的, 只有可選類型才可以為空. 為了和Swift更好的結(jié)合, Objective-C中也加入了 可空性標(biāo)注 , 可以標(biāo)注是否期望一個(gè)值是否可空.茉继、

  • __kindof修飾符

    通過使用 kindof 聲明某對象是某種類型, 讓編譯器知道對象是某種類型或者該類型的子類, 可以用在泛型參數(shù)里. 使用 kindof 對類型進(jìn)行約束, 比指定某種類型或者id類型更靈活一些.

__kindof 這修飾符還是很實(shí)用的咧叭,解決了一個(gè)長期以來的小痛點(diǎn),拿原來的 UITableView 的這個(gè)方法來說:

<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
|

1

|

  • (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;

|

使用時(shí)前面基本會(huì)使用 UITableViewCell 子類型的指針來接收返回值烁竭,所以這個(gè) API 為了讓開發(fā)者不必每次都蛋疼的寫顯式強(qiáng)轉(zhuǎn)菲茬,把返回值定義成了 id 類型,而這個(gè) API 實(shí)際上的意思是返回一個(gè) UITableViewCell 或 UITableViewCell 子類的實(shí)例派撕,于是新的 __kindof 關(guān)鍵字解決了這個(gè)問題:

<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
|

1

|

  • (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;

|

既明確表明了返回值婉弹,又讓使用者不必寫強(qiáng)轉(zhuǎn)。再舉個(gè)帶泛型的例子终吼,UIView 的 subviews 屬性被修改成了:

<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
|

1

|

@property (nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews;

|

這樣镀赌,寫下面的代碼時(shí)就沒有任何警告了:

<colgroup><col style="width: 130px;"><col style="width: 130px;"></colgroup>
|

1

|

UIButton *button = view.subviews.lastObject;

|

  • 地址消毒劑

    Xcode7能夠在編譯應(yīng)用時(shí)加入地址消毒劑, 用以幫助捕獲和調(diào)試內(nèi)存沖突. 堆棧緩沖溢出, 野指針等內(nèi)存沖突導(dǎo)致的崩潰Objective-C和C代碼很容易產(chǎn)生. 內(nèi)存問題可能導(dǎo)致app崩潰, 也可能讓app發(fā)生詭異的行為. 由于難以復(fù)現(xiàn), 并且bug現(xiàn)象和源頭可能相距很遠(yuǎn)(比如登陸功能有野指針可能導(dǎo)致商品的名稱顯示不正常), 內(nèi)存問題很難追蹤.

    在build scheme里面啟用地址消毒劑, 你就可以在發(fā)生問題的時(shí)候定位內(nèi)存地址. Xcode同時(shí)也會(huì)提供諸如地址和對象的關(guān)系, 對象分配和回收的信息, 從而幫助你定位和解決為題. 地址消毒劑的性能很好. 支持模擬器和真實(shí)設(shè)備, 支持iOS和 OS X.

  • UI 錄制

    UI test方法可以通過錄制UI交互操作的方式創(chuàng)建. 當(dāng)用戶和應(yīng)用交互的時(shí)候, Xcode在你的測試方法里面注入代碼, 這些代碼找到你app的UI元素, 訪問他們的屬性, 調(diào)用他們的事件.

  • 正確性和性能

    XCTest現(xiàn)在為定位UI元素, 訪問元素的屬性, 調(diào)用事件提供了豐富的特性. 在UITest中, assert, 性能監(jiān)視等同樣支持.

  • 代碼覆蓋率

    在scheme里啟用代碼覆蓋率功能, 就可以對代碼覆蓋率進(jìn)行可視化. 在測試報(bào)告里可以看到哪個(gè)文件里的哪個(gè)函數(shù)的哪行代碼是執(zhí)行了還是沒執(zhí)行.代碼編輯器也可以顯示代碼的覆蓋率信息, 讓你看到在一此測試中哪行代碼執(zhí)行了, 哪行代碼沒執(zhí)行.

  • Xcode Server.

    Xcode的測試功能已經(jīng)和Xcode Server完整的集成. 在Xcode Server上你在一個(gè)hands-off(放手, 類似于騎自行車大撒把)的環(huán)境里, 在多個(gè)設(shè)備上執(zhí)行測試, 反復(fù)的執(zhí)行, 統(tǒng)一和更好的評估app的正確性和性能. 新的Xcode Server 報(bào)表格式會(huì)顯示一個(gè)項(xiàng)目中的趨勢, 回歸反復(fù)進(jìn)行的測試.

    在你自己的設(shè)備上開發(fā)

    在Xcode7里面, 不再需要購買開發(fā)者以及進(jìn)行繁瑣的設(shè)置, 你就可以在任意的設(shè)備上進(jìn)行開發(fā)和調(diào)試了. 只需要注冊一個(gè)Apple Id.

·ios9之后的Top Layout Guide與Bottom Layout Guide

http://blog.csdn.net/moon_prince2013/article/details/50067663

image.png
image.png

勾選第二個(gè) 改成bottom space

1.狀態(tài)欄的警告

<Error>: CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

<Error>: CGContextTranslateCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

<Error>: CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

出錯(cuò)原因:設(shè)置 app 的狀態(tài)欄樣式的時(shí)候,使用了舊的方式际跪,在 info.plist 里面的 View controller-based status bar appearance 默認(rèn)會(huì)為 YES商佛,即使不設(shè)置也是 YES喉钢,但一般 iOS6 的時(shí)候?yàn)榱嗽O(shè)置狀態(tài)欄樣式,需要將其設(shè)為NO良姆,iOS7肠虽,8也兼容,但是到了iOS9 就會(huì)報(bào)警告玛追。

解決辦法:

刪除原先的設(shè)置代碼税课,通常老的設(shè)置方式是這樣的:

//設(shè)置狀態(tài)欄的白色

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

刪除的原因見下:

// Setting the statusBarStyle does nothing if your application is using the default UIViewController-based status bar system.

@property(readwrite, nonatomic) UIStatusBarStyle statusBarStyle NS_DEPRECATED_IOS(2_0, 9_0, "Use -[UIViewController preferredStatusBarStyle]");

  • (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 9_0, "Use -[UIViewController preferredStatusBarStyle]");

修改方式是在 Info.plist 文件中做如下修改:

將 View controller-based status bar appearance 刪除(默認(rèn)為 YES),或設(shè)置為YES:

對應(yīng)的 plist 里的 XML源碼:

<key>UIViewControllerBasedStatusBarAppearance</key>

<true/>

看起來長這樣:

然后使用新的方式來實(shí)現(xiàn)狀態(tài)欄的樣式:

  • (UIStatusBarStyle)preferredStatusBarStyle;

  • (UIViewController *)childViewControllerForStatusBarStyle;

  • (void)setNeedsStatusBarAppearanceUpdate

比如痊剖,你想將狀態(tài)欄設(shè)置為白色韩玩,就可以這樣寫:

//設(shè)置狀態(tài)欄的白色

-(UIStatusBarStyle)preferredStatusBarStyle

{

return UIStatusBarStyleLightContent;

}

記得要 clean 下或者刪除應(yīng)用程序重新運(yùn)行

2.運(yùn)行報(bào)錯(cuò) there is an intenal API error

Xcode7 調(diào)試 iOS8.x 的真機(jī),需要確保項(xiàng)目名改為英文邢笙,中間含有中文會(huì)報(bào)錯(cuò) there is an intenal API error

按照下面的步驟檢查:

bulid settings -> packaging -> product name

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末啸如,一起剝皮案震驚了整個(gè)濱河市侍匙,隨后出現(xiàn)的幾起案子氮惯,更是在濱河造成了極大的恐慌,老刑警劉巖想暗,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妇汗,死亡現(xiàn)場離奇詭異,居然都是意外死亡说莫,警方通過查閱死者的電腦和手機(jī)杨箭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來储狭,“玉大人互婿,你說我怎么就攤上這事×杀罚” “怎么了慈参?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長刮萌。 經(jīng)常有香客問我驮配,道長,這世上最難降的妖魔是什么着茸? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任壮锻,我火速辦了婚禮,結(jié)果婚禮上涮阔,老公的妹妹穿的比我還像新娘猜绣。我一直安慰自己,他們只是感情好敬特,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布途事。 她就那樣靜靜地躺著验懊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尸变。 梳的紋絲不亂的頭發(fā)上义图,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機(jī)與錄音召烂,去河邊找鬼碱工。 笑死,一個(gè)胖子當(dāng)著我的面吹牛奏夫,可吹牛的內(nèi)容都是我干的怕篷。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼酗昼,長吁一口氣:“原來是場噩夢啊……” “哼廊谓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起麻削,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤蒸痹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后呛哟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叠荠,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年扫责,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榛鼎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,768評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鳖孤,死狀恐怖者娱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情苏揣,我是刑警寧澤黄鳍,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站腿准,受9級特大地震影響际起,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吐葱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一街望、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弟跑,春花似錦灾前、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蔫敲。三九已至,卻和暖如春炭玫,著一層夾襖步出監(jiān)牢的瞬間奈嘿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工吞加, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裙犹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓衔憨,卻偏偏與公主長得像叶圃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子践图,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評論 2 350