Swift 3.0~常用知識(shí)

The Swift Programming Language (Swift 3.1)

最全的 Swift 4 新特性解析

  • Swift中文件權(quán)限

fileprivate :如名字一樣,只有這個(gè)文件才能訪問(wèn)
private: 只能在作用域訪問(wèn)
interal: 默認(rèn)焕济,在整個(gè)模塊可以訪問(wèn).
public: 在同一個(gè)模塊里面可以繼承或者重寫,在模塊外可以訪問(wèn),但不可以重寫和繼承
open:在所有模塊都可以訪問(wèn)脂凶,重寫和繼承
權(quán)限由大到小排序:
open > public > interal > fileprivate > private

  • 關(guān)鍵字
  • final:
- 可以通過(guò)把方法永品,屬性或下標(biāo)標(biāo)記為`final`來(lái)防止它們被重寫虱歪,只需要在聲明關(guān)鍵字前加上`final`修飾符即可(例如:`final var`时迫,`final func`娇昙,`final class func`,以及`final subscript`)       
- 可以通過(guò)在關(guān)鍵字`class`前添加`final`修飾符(`final class`)來(lái)將整個(gè)類標(biāo)記為 `final` 的剥哑。這樣的類是不可被繼承的硅则,試圖繼承這樣的類會(huì)導(dǎo)致編譯報(bào)錯(cuò)。
  • staic: 在方法的func關(guān)鍵字之前加上關(guān)鍵字static株婴,來(lái)指定類型方法怎虫。類還可以用關(guān)鍵字class來(lái)允許子類重寫父類的方法實(shí)現(xiàn)。
  • Swift調(diào)用OC代碼
1.在Swift項(xiàng)目中創(chuàng)建OC文件時(shí)困介,Xcode會(huì)提示是否需要?jiǎng)?chuàng)建橋接文件大审,點(diǎn)擊創(chuàng)建橋接文件,會(huì)生成“工程名-Bridging-Header.h”文(也可手動(dòng)創(chuàng)建Header File座哩,命名為XXX-Bridging-Header.h徒扶,xxx為工程名稱)
2.配置.h文件位置:TARGETS->Build Settings->Swift Compiler->Objective-C Bridging Header,設(shè)置路徑如工程名為為Demo根穷,則此處可配置為:Demo/Demo-Bridging-Header.h姜骡。(前提Demo-Bridging-Header.h在Demo工程根目錄下)
3.在XXX-Bridging-Header.h文件中導(dǎo)入OC頭文件。如:#import "AFNetworking.h"
  • OC調(diào)用Swift代碼
1.在OC項(xiàng)目中創(chuàng)建Swift文件時(shí)缠诅,Xcode會(huì)提示是否需要?jiǎng)?chuàng)建橋接文件溶浴,點(diǎn)擊創(chuàng)建橋接文件,會(huì)生成“工程名-Bridging-Header.h”文(也可手動(dòng)創(chuàng)建)
2.配置:TARGETS ->Build Settings -> Packaging ,設(shè)置Defines Module為YES管引,Product Module Name為工程名稱(默認(rèn)為工程的名字)
3.在OC需要用到Swift的文件中導(dǎo)入文件 "Product Module Name-Swift.h"士败, Product Module Name 默認(rèn)是工程的名字,直接導(dǎo)入#import "工程名-Swift.h"
(注意:導(dǎo)入的是XXX.Swift.h褥伴,而不是系統(tǒng)提示的XXX-Bridging-Header.h)
  • 聲明特性
    • 系統(tǒng)版本判斷
if #available(iOS 9.0, *) {
   if let options = options as? [UIApplicationOpenURLOptionsKey : Any] {
        if let sourceAppKey = options[.sourceApplication] {
             sourceApplicationKey = (sourceAppKey as? String)!
        }
    }
} else {
    // Fallback on earlier versions
    if let options = options as? String {
        if options.characters.count > 0 {
            sourceApplicationKey = options
        }
    }
}
  • 忽略函數(shù)返回值
@discardableResult
func test() -> Bool {
    return false
}
  • 某個(gè)聲明已經(jīng)被重命名
@available(*, unavailable, renamed:"MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol
  • 平臺(tái)可用性
@available(iOS 10.0, macOS 10.12, *)
class MyClass {
}
@available(iOS, introduced: 2.0, deprecated: 10.0, message: "Please use openURL:options:completionHandler: instead")
open func openURL(_ url: URL) -> Bool {}
  • 使用OC方法調(diào)用
    以下方法為Swift中定義的方法谅将,若想使用OC方法的命名方式定義,則使用@objc(參數(shù)個(gè)數(shù)需一直)重慢,如下:
@objc(beginLogPage:)
public class func beginLogPage(identifier: String) {  
}
  • 閉包弱引用

Unowned 還是 Weak饥臂?生命周期和性能對(duì)比

  • unowned
 - 原始實(shí)例永遠(yuǎn)不會(huì)為 nil,閉包可以直接使用它似踱,并且直接定義為顯式解包可選值隅熙。當(dāng)原始實(shí)例被析構(gòu)后,在閉包中使用這個(gè)捕獲值將導(dǎo)致崩潰核芽。
 -  閉包和捕獲對(duì)象的生命周期相同囚戚,所以對(duì)象可以被訪問(wèn),也就意味著閉包也可以被訪問(wèn)轧简。外部對(duì)象和閉包有相同的生命周期驰坊,如 `[unowned self]`
  • weak:
    • 如果捕獲原始實(shí)例在使用過(guò)程中可能為 nil ,必須將引用聲明為 weak哮独, 并且在使用之前驗(yàn)證這個(gè)引用的有效性拳芙。
    • 閉包的生命周期和捕獲對(duì)象的生命周期相互獨(dú)立察藐,當(dāng)對(duì)象不能再使用時(shí),閉包依然能夠被引用舟扎。在使用它之前驗(yàn)證一下它是否為 nil(請(qǐng)不要對(duì)它進(jìn)行強(qiáng)制解包).如:[weak delegate = self.delegate!]
class aClass{
    var value = 1
}
var c1 = aClass()
var c2 = aClass()

var fSpec = { [unowned c1, weak c2] in
    c1.value += 1
    if let c2 = c2 {
        c2.value += 1
    }
}
fSpec()
print(c1.value,c2.value) //Prints 2 and 2    
  • 判斷字符串是否包含另一字符串
if (strA.components(separatedBy: "strB").count)! > 1 {
    println("包含")  
} else {  
    println("不包含")  
}

>= iOS iOS 8 NSString方法containsString
let str: String = "123test4"
if (str as NSString).contains("test") {
    print("包含")
}

if str.contains("test") {
    print("包含")
}
  • 方法中修改可變字典分飞、數(shù)組等
var pageInfoDic = [String: AnyObject]()     
setDic(origin: &pageInfoDic, value: pageInfo.pageIdentifier, key: "PID")   
class func setDic(origin dic: inout [String: AnyObject], value: Any?, key: String) {
        guard let value = value else {
            return
        }
        if let value = value as? String {
            if value == "" {
                return
            }
        }
        
        dic[key] = value as AnyObject?
    }
  • 解檔枚舉類型
public enum UserSex: Int {
    case EGSexFemale = 0
    case EGSexMale
    case EGSexUnknown
}

public class EGUserInfo: NSObject,NSCoding {
    public var userSex: UserSex = .EGSexUnknown
}

// MARK:- 歸檔及解檔
public func encode(with aCoder: NSCoder) {
        aCoder.encode(userSex.rawValue, forKey: "userSex")
}

required public init?(coder aDecoder: NSCoder) {
        super.init()
        userSex = UserSex(rawValue: aDecoder.decodeInteger(forKey: "userSex"))! 
}
  • 擴(kuò)展通知,方便調(diào)用

方法1:

//  添加通知
NotificationCenter.default.addObserver(self, selector: #selector(enterForeground(notify:)), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
//  發(fā)送通知
NotificationCenter.default.post(name: NSNotification.Name("foreground"), object: nil)

方法2:

import Foundation
class TestDemo: NSObject {
    func testDemo() {
        //  添加通知
        NotificationCenter.default.addObserver(self, selector: .foregroundNotify, name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
    }

    // MARK: - 通知執(zhí)行方法 
    func enterForeground(notify: Notification) -> Void {
        print("1111")
    }

    // MARK: - 析構(gòu)函數(shù)
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

// MARK: - Selector 擴(kuò)展
fileprivate extension Selector {
    static let foregroundNotify = #selector(TestDemo.enterForeground(notify:))
}
  • GCD
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0/*延遲時(shí)長(zhǎng)浆竭,單位秒*/) {
            print("延遲1s執(zhí)行")
}
//  異步線程
DispatchQueue.global().async {
      //  主線程
      DispatchQueue.main.async {
      }
}
  • 只讀屬性
//  懶加載
lazy var names: NSArray = {
    let names = NSArray()
    print("只在首次訪問(wèn)輸出")
    return names
}()

var appVersion: String {
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] {
        return version as! String
    }
    return ""
}
  • 可選類型類型轉(zhuǎn)換
var optionStr: String?
optionStr = "123"
//  1.拆包判斷
if let str = optionStr as? String {
    print("string")
} else {
    print("not string")
}
//  2.map
if let string = optionStr.map({ $0 as String }) {
    print("map, string")
} else {
    print("map, not string")
}
//  3.flatMap
if let string = optionStr.flatMap({ $0 as? String }) {
    print("flatMap, string")
} else {
    print("flatMap, not string")
}
//  類型嵌套及解包
class func savePolicy(info: AnyObject) {
        if let policyInfo = info as? NSDictionary,
            let policyDic = policyInfo["policy"] as? NSDictionary,
            let failDic = policyDic["fail"] as? NSDictionary
        {
        }
}
  • 處理不等長(zhǎng)的數(shù)組
let array2 = ["張三","李四","王五","趙六"]
let array1 = [0,1,2,3,4]
for (index, name) in zip(array1, array2) {
    print(name)
    print(array2[index])
}
for (model, viewController) in zip(models, viewControllers) {
    viewController.model = model
}
  • extension使用
extension UIView {
    func with(backgroundColor: UIColor) -> Self {
        self.backgroundColor = backgroundColor
        return self
    }
    
    func with(cornerRadius: CGFloat) -> Self {
        self.layer.cornerRadius = 3
        return self
    }
}
//  使用 
override func viewDidLoad() {
    super.viewDidLoad()

    let view = UIView(frame: CGRect(x: 30, y: 30, width: 100, height: 100))
            .with(backgroundColor: .blue)
            .with(cornerRadius: 3)
    self.view.addSubview(view)
}
  • 代碼注釋
    在OC中使用以下方式可對(duì)方法進(jìn)行分割分類
#pragma mark - 表示方法分割線

但在Swift中需使用以下方法

// MARK: - 表示方法分割線

其他方法

// FIXME: - 在注釋中用 FIXME 標(biāo)記某代碼是錯(cuò)誤的浸须,而且不能工作,需要及時(shí)糾正的情況邦泄。
// TODO: - 表示需要實(shí)現(xiàn)删窒,但目前還未實(shí)現(xiàn)的功能。

當(dāng)然FIXME和TODO若查找太麻煩顺囊,可以讓其在編譯時(shí)報(bào)警告肌索,提醒開發(fā)者,可能有問(wèn)題的地方特碳,方法如下:

工程 -> TARGETS -> Build Phases -> + -> New Run Script Phase诚亚,添加相應(yīng)腳本,內(nèi)容如下:

image.png
Swift腳本:
TAGS="TODO:|FIXME:"
echo "searching ${SRCROOT} for ${TAGS}"
find "${SRCROOT}" \( -name "*.swift" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/"

OC腳本:
KEYWORDS="TODO:|FIXME:|\?\?\?:|\!\!\!:"  
find "${SRCROOT}" \( -name "*.h" -or -name "*.m" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($KEYWORDS).*\$" | perl -p -e "s/($KEYWORDS)/ warning: \$1/"  

重新運(yùn)行工程后午乓,便會(huì)看到相應(yīng)的警告提示站宗,如下圖所示:

image.png
// Swift 2
var wordArray = ["Apple", "Carrot", "Peanut Butter"]
wordArray.append("Hummus")
wordArray.insert("Greek Salad", atIndex: 0)
// Find the objects to remove
var wordsToDelete: [String] = [String]()
for word in wordArray {
    if word.lowercaseString.characters.contains("p") {
        wordsToDelete.append(word)
    }
}
// Find the index and remove each object
for word in wordsToDelete {
    if let index = wordArray.indexOf(word) {
        wordArray.removeAtIndex(index)
    }
}
  • 打印對(duì)象地址
在debug區(qū)域輸入:
fr v -R 對(duì)象名稱
結(jié)果如下:
(lldb) fr v -R a
(Swift.Array<Swift.Int>) a = {
  _buffer = {
    _storage = {
      rawValue = 0x0000600000079500 {
        Swift._ContiguousArrayStorageBase = {
          Swift._SwiftNativeNSArrayWithContiguousStorage = {
            Swift._SwiftNativeNSArray = {}
          }
          countAndCapacity = {
            _storage = {
              count = {
                _value = 3
              }
              _capacityAndFlags = {
                _value = 6
              }
            }
          }
        }
      }
    }
  }
}
  • Range使用
    swift中Range<String.Index>非常麻煩梢灭,可以將String轉(zhuǎn)為NSString結(jié)合NSRange使用
let levels = "ABCDE"
let nsRange = NSMakeRange(1, 4)
let newString = (levels as NSString).replacingCharacters(in: nsRange, with: "AAAA")
print(newString)
  • 數(shù)組遍歷
let arr: NSArray = [1, 2, 3, 4, 5]
for (index, num) in arr.enumerated() {
    result += num as! Int
    if index == 2 {
        break
    }
}
print(result)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蒸其,隨后出現(xiàn)的幾起案子敏释,更是在濱河造成了極大的恐慌,老刑警劉巖摸袁,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钥顽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡靠汁,警方通過(guò)查閱死者的電腦和手機(jī)蜂大,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蝶怔,“玉大人县爬,你說(shuō)我怎么就攤上這事√硪辏” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵察迟,是天一觀的道長(zhǎng)斩狱。 經(jīng)常有香客問(wèn)我耳高,道長(zhǎng),這世上最難降的妖魔是什么所踊? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任泌枪,我火速辦了婚禮,結(jié)果婚禮上秕岛,老公的妹妹穿的比我還像新娘碌燕。我一直安慰自己,他們只是感情好继薛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布修壕。 她就那樣靜靜地躺著,像睡著了一般遏考。 火紅的嫁衣襯著肌膚如雪慈鸠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天灌具,我揣著相機(jī)與錄音青团,去河邊找鬼。 笑死咖楣,一個(gè)胖子當(dāng)著我的面吹牛督笆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播诱贿,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼娃肿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了瘪松?” 一聲冷哼從身側(cè)響起咸作,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宵睦,沒(méi)想到半個(gè)月后记罚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壳嚎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年桐智,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烟馅。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡说庭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出郑趁,到底是詐尸還是另有隱情刊驴,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站捆憎,受9級(jí)特大地震影響舅柜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躲惰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一致份、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧础拨,春花似錦氮块、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至僚焦,卻和暖如春锰提,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芳悲。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工立肘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人名扛。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓谅年,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親肮韧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子融蹂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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

  • 問(wèn)題 1)柯里化,通過(guò)柯里化弄企,改造target-action超燃,因?yàn)閟elector只能使用字符串,在編譯時(shí)無(wú)法發(fā)現(xiàn)...
    lanjing閱讀 3,511評(píng)論 3 19
  • 轉(zhuǎn)載自:https://github.com/Tim9Liu9/TimLiu-iOS 目錄 UI下拉刷新模糊效果A...
    袁俊亮技術(shù)博客閱讀 11,928評(píng)論 9 105
  • 嗯哼嗯哼蹦擦擦~~~ 轉(zhuǎn)載自:https://github.com/Tim9Liu9/TimLiu-iOS 目錄 ...
    philiha閱讀 4,899評(píng)論 0 6
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)拘领、插件意乓、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,109評(píng)論 4 62
  • 還是像高中那樣老師教什么就學(xué)什么,把全部力氣都放在學(xué)這個(gè)上面约素,然后其他的事情一點(diǎn)不做失尖,不去想未來(lái)窟蓝,活的果然是最輕松...
    掉二塔閱讀 295評(píng)論 0 1