`
啸笑天
  • 浏览: 3465465 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

Swift Tips(version4.0+ xcode9.0+)

 
阅读更多

原文地址:https://github.com/easyui/blog/blob/master/Swift/2017-09-26-Swift-Tips%5BV4.0%2B%2CXcode9.0%2B%5D.md

 

:smile:Xcode 9 中同时集成了 Swift 3.2 和 Swift 4。

  • Swift 3.2 完全兼容 Swift 3.1,并会在过时的语法或函数上报告警告。
  • Swift 3.2 具有 Swift 4 的一些写法,但是性能不如 Swift 4。
  • Swift 3.2 和 Swift 4 可以混合编译,可以指定一部分模块用 Swift 3.2 编译,一部分用 Swift 4 编译。
  • 迁移到 Swift 4 后能获得 Swift 4 所有的新特性,并且性能比 Swift 3.2 好。

:smile:dynamic

Swift 3中dynamic是自带@objc,但是Swift 4中,dynamic不在包含@objc了。所以有些需要使用到@objc标明的方法,在Swift 4得补回去。

:smile:@objc

在项目中想把 Swift 写的 API 暴露给 Objective-C 调用,需要增加 @objc。在 Swift 3 中,编译器会在很多地方为我们隐式的加上 @objc,例如当一个类继承于 NSObject,那么这个类的所有方法都会被隐式的加上 @objc。
swift
class MyClass: NSObject {
func print() { ... } // 包含隐式的 @objc
func show() { ... } // 包含隐式的 @objc
}

这样很多并不需要暴露给 Objective-C 也被加上了 @objc。大量 @objc 会导致二进制文件大小的增加。

在 Swift 4 中,隐式 @objc 自动推断只会发生在很少的当必须要使用 @objc 的情况,比如:

1、复写父类的 Objective-C 方法

2、符合一个 Objective-C 的协议

其它大多数地方必须手工显示的加上 @objc。

减少了隐式 @objc 自动推断后,Apple Music app 的包大小减少了 5.7%。

:smile:The use of Swift 3 @objc inference in Swift 4 mode is deprecated. Please address deprecated @objc inference warnings, test your code with “Use of deprecated Swift 3 @objc inference” logging enabled, and then disable inference by changing the "Swift 3 @objc Inference" build setting to "Default" for the "ProjectName" target.

到target->build setting->swift3 @objc inference 设置为off 

:smile:枚举更swift化

AVMetadataCommonKeyTitl -> AVMetadataKey.commonKeyTitle

AVMetadataKeySpaceCommon -> AVMetadataKeySpace.common

:smile:AVPlayerLayer的videoGravity属性(其实是iOS11的变化)

swift3
swift
/*!
@property videoGravity
@abstract A string defining how the video is displayed within an AVPlayerLayer bounds rect.
@discusssion Options are AVLayerVideoGravityResizeAspect, AVLayerVideoGravityResizeAspectFill 
and AVLayerVideoGravityResize. AVLayerVideoGravityResizeAspect is default. 
See <AVFoundation/AVAnimation.h> for a description of these options.
*/
open var videoGravity: String  

swift4
swift
/*!
@property videoGravity
@abstract A string defining how the video is displayed within an AVPlayerLayer bounds rect.
@discusssion Options are AVLayerVideoGravityResizeAspect, AVLayerVideoGravityResizeAspectFill 
and AVLayerVideoGravityResize. AVLayerVideoGravityResizeAspect is default. 
See <AVFoundation/AVAnimation.h> for a description of these options.
*/
open var videoGravity: AVLayerVideoGravity

:smile:extension 中可以访问 private 的属性

struct Date {
    private let secondsSinceReferenceDate: Double
}
extension Date: Equatable {
    static func ==(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate == rhs.secondsSinceReferenceDate
    }
}
extension Date: Comparable {
    static func <(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate < rhs.secondsSinceReferenceDate
    }
}

但是在 Swift 3 中,编译就报错了,因为 extension 中无法获取到 secondsSinceReferenceDate 属性,因为它是 private 的。于是在 Swift 3 中,必须把 private 改为 fileprivate,且在同一个文件里。

在 Swift 4 中,private 的属性的作用域扩大到了 extension 中

:smile: Associated Type 可以追加 Where 约束语句

   protocol Sequence {
    associatedtype Element where Self.Element == Self.Iterator.Element
    // ...
   }

它限定了 Sequence 中 Element 这个类型必须和 Iterator.Element 的类型一致。

通过 where 语句可以对类型添加更多的约束,使其更严谨,避免在使用这个类型时做多余的类型判断。

:smile: 类型和协议的组合类型

在 Swift 4 中,可以把类型和协议用 & 组合在一起作为一个类型使用,就可以像下面这样写了:
```swift
protocol Shakeable {
func shake()
}

extension UIButton: Shakeable { /* ... / }
extension UISlider: Shakeable { /
 ... */ }

func shakeEm(controls: [UIControl & Shakeable]) {
for control in controls where control.isEnabled {
control.shake()
}// Objective-C API
@interface NSCandidateListTouchBarItem : NSTouchBarItem
@property (nullable, weak) NSView *client;
@end
}
```

在 Swift 4 中,这类 API 做了优化,改成了这样类型的声明就更加严谨了:
swift
class NSCandidateListTouchBarItem<CandidateType: AnyObject> : NSTouchBarItem {
var client: (NSView & NSTextInputClient)?
}

:smile: KVC:新的 Key Paths 语法

Swift 3 中 Key Paths 的写法:
```swift
class Kid: NSObject {
@objc var nickname: String = ""
@objc var age: Double = 0.0
@objc var friends: [Kid] = []
}

var ben = Kid(nickname: "Benji", age: 5.5)

let kidsNameKeyPath = #keyPath(Kid.nickname)

let name = ben.valueForKeyPath(kidsNameKeyPath)
ben.setValue("Ben", forKeyPath: kidsNameKeyPath)
```
上面是在swift3中使用的方法,在oc中能够很好的运行,可在swift中它有着明显的不足:

1.返回值是Any类型,错误的赋值可能导致运行时错误

2.这个类必须继承NSObject,而swift是可以不继承自任何类的

Swift 4 中创建一个 KeyPath 用 \ 作为开头:

\Kid.nickname

上面的代码在 Swift 4 中就可以这样写:
```swift
struct Kid {
var nickname: String = ""
var age: Double = 0.0
var friends: [Kid] = []
}

var ben = Kid(nickname: "Benji", age: 8, friends: [])

let name = ben[keyPath: \Kid.nickname]
ben[keyPath: \Kid.nickname] = "BigBen"
```
相比 Swift 3,Swift 4 的 Key Paths 具有以下优势:

  • 类型可以定义为 class、struct
  • 定义类型时无需加上 @objcMembers、dynamic 、@objc等关键字
  • 性能更好
  • 类型安全和类型推断,例如 ben.valueForKeyPath(kidsNameKeyPath) 返回的类型是 Any,ben[keyPath: \Kid.nickname] 直接返回 属性的 类型
  • 可以在所有值类型上使用

:smile: KVO

依然只有 NSObject 才能支持 KVO。

Swift 4中的一个对此有影响的改变是继承 NSObject 的 swift class 不再默认全部 bridge 到 OC。

然而 KVO 又是一个纯 OC 的特性,所以如果是 swift class 需要在声明的时候增加 @objcMembers 关键字。否则在运行的时候你会得到一个 error:

fatal error: Could not extract a String from KeyPath 
Swift.ReferenceWritableKeyPath

一个好消息是不需要在对象被回收时手动 remove observer。但是这也带来了另外一个容易被忽略的事情:观察的闭包没有被强引用,需要我们自己添加引用,否则当前函数离开后这个观察闭包就会被回收了。KVO 之后返回的是一个 NSKeyValueObservation 实例,需要自己控制这个实例的生命周期。
```swift
@objcMembers class OCClass: NSObject {
dynamic var name: String

init(name: String) {
    self.name = name
}

}

class ViewController: UIViewController {

var swiftClass: OCClass!
var ob: NSKeyValueObservation!

override func viewDidLoad() {
    super.viewDidLoad()

    swiftClass = OCClass(name: "oc")
    ob = swiftClass.observe(\.name) { (ob, changed) in
        let new = ob.name
        print(new)
    }
    swiftClass.name = "swift4"
}

}
```

:smile: 下标支持泛型

有时候会写一些数据容器,Swift 支持通过下标来读写容器中的数据,但是如果容器类中的数据类型定义为泛型,以前的下标语法就只能返回 Any,在取出值后需要用 as? 来转换类型。Swift 4 定义下标也可以使用泛型了。
```swift
struct GenericDictionary {
private var data: [Key: Value]

init(data: [Key: Value]) {
    self.data = data
}

subscript<T>(key: Key) -> T? {
    return data[key] as? T
}

}

let dictionary = GenericDictionary(data: ["Name": "Xiaoming"])

let name: String? = dictionary["Name"] // 不需要再写 as? String
```

:smile: Unicode 字符串在计算 count 时的正确性改善

在 Unicode 中,有些字符是由几个其它字符组成的,比如 é 这个字符,它可以用 \u{E9} 来表示,也可以用 e 字符和上面一撇字符组合在一起表示 \u{65}\u{301}。

考虑以下代码:
```swift
var family = "

分享到:
评论

相关推荐

    全新版本全新工具-进击Apple IOS 13开发实战 SwiftUI 5.1+Xcode11 SwiftUI实战教程

    全新版本全新工具-进击Apple IOS 13的SwiftUI开发实战,使用最新的Mac OS X集成开发工具Xcode11进行SwiftUI构建用户界面,让同学们最近的距离接触IOS与用户界面开发。课程分为了SwiftUI开发的基础部分与进阶部分,...

    Swift中的可自定义雷达图-Swift开发

    TKRadarChart Swift Requirements iOS 8.0+ Xcode 9.0 Swift 4.0安装中的可定制雷达图CocoaPods您可以通过添加TKRadarChart在Swift Requirements iOS 8.0+ Xcode 9.0 Swift 4.0安装中的可定制雷达图安装CocoaPods您...

    最新iOS11开发教程swift4+xcode9

    最新iOS11开发教程swift4+xcode9,iOS 11开发概述 iOS 11新特性 编写第一个iOS 11应用 4 创建iOS11项目 4 运行iOS11程序 7 iOS11模拟器介绍 iOS11Main.storyboard文件编辑界面 编写第一个iOS11代码Hello,World 15 ...

    swift4.0基础教程

    这篇“Swift 4.0基础教程”旨在帮助初学者掌握Swift 4.0的关键概念,并利用Xcode 9.0这一最新的开发工具来创建iOS 11应用程序。 首先,Swift 4.0引入了对元组解包的增强,允许在单行赋值时为元组中的元素指定名字,...

    Windows+VMware+MacOS10.8.2+Xcode环境搭建

    本篇主要介绍如何在Windows操作系统上使用VMware虚拟机来安装并配置MacOS 10.8.2系统,以及在此基础上安装Xcode开发工具。这是一条龙式的搭建过程,适合初学者和需要跨平台开发的工程师参考。 首先,我们要在...

    Xcode9.0 FileProvider.framework

    **Xcode 9.0中的FileProvider.framework** 在iOS开发中,`FileProvider.framework`是一个至关重要的组件,它首次在iOS 11中引入,并在Xcode 9.0中得到支持。这个框架允许应用程序提供对文件的访问,使得用户可以在...

    swift4.0大学霸

    在实际开发中,Swift 4.0与Xcode 9.0的集成提供了更好的调试工具和性能分析器,帮助开发者定位和解决性能瓶颈。同时,Swift Package Manager的完善使得Swift项目管理和依赖库的管理更加标准化和高效。 综上所述,...

    低版本xcode 需要的ios 真机调试的SDK>9.0

    在iOS应用开发中,Xcode是苹果官方提供的集成开发环境(IDE),用于编写Objective-C、Swift等语言的代码。在某些情况下,开发者可能需要使用较旧版本的Xcode来兼容老款设备或特定项目需求。当遇到“低版本Xcode需要...

    Swift Apprentice v4.0 (iOS12 & Swift4.2 & Xcode10)

    Learn how to program with Swift. Currently updated to: Platform: iOS12; Language: Swift4.2; Editor: Xcode10

    AnyFormatKit:Swift中的简单文本格式

    演示版要求iOS 8.0以上迅捷4.0+ Xcode 9.0以上SwiftUI AnyFormatKit具有SwiftUI版本,作为单独的框架存在 迁移指南AnyFormatKit 0.2.0迁移指南AnyFormatKit 1.0.0迁移指南AnyFormatKit 2.4.0迁移指南 安装 可可豆可...

    svn+xcode配置

    - 打开Xcode项目,选择菜单栏的“File” -&gt; “Source Control” -&gt; “Configure...”,在弹出的窗口中,选择“Version Control”为“Subversion”。 - 在“Repository URL”字段中填入你的svn仓库地址。 - 点击...

    Xcode9.0 11.0 (15A5304f) DeveloperDiskImage.dmg 下载

    Xcode9.0 11.0 (15A5304f) DeveloperDiskImage.dmg 下载,Xcode8.* 运行iOS11.0系统的设备,需要添加的DeveloperDiskImage.dmg文件,下载解压后,直接将文件夹复制到/Applications/Xcode.app/Contents/Developer/...

    自定义演示者和适用于iOS的更好的View Controller演示-Swift开发

    需求Swift 4.0+ Xcode 9+ iOS 9.0+ PresenterKit适用于iOS的自定义演示者和更好的视图控制器演示需求Xcode 11.4+ Swift 5.2+ iOS 11.0+ SwiftLint安装CocoaPods pod'PresenterKit','〜&gt; 6.1.0'#开发分支pod' ...

    Swift4.0语言快速入门

    Xcode9.0支持Swift4.0,为编写、编译和测试Swift程序提供了必要的工具。 在学习过程中,建议先熟悉Xcode9.0界面,了解Xcode的各个组件和文档的更新方式。创建一个Swift项目是编写第一个程序的第一步。接下来,通过...

    适用于iOS的易于使用的日历(Swift 5.0)-Swift开发

    要求iOS 8.0+ XCode 9.0+ Swift 4.2安装CocoaPods pod'KDCalendar','〜&gt; 1.8.9'Carthage将此添加到您的Cartfile,然后运行carthage更新:github“ mmick66 / CalendarView”“ master” Swift Package Manager转到...

    苹果狮子(BT)+xcode4.2.1(官方)下载地址

    这个版本的Xcode包含了Interface Builder(设计用户界面的工具)、Instruments(性能分析工具)以及Apple的编程语言Objective-C和Swift的开发环境。Xcode 4.2.1支持iOS 5,这使得开发者能够创建针对iPhone、iPad和...

    iOS Apprentice 6th(swift4+xcode9)

    《iOS Apprentice 6th》是针对Swift 4和Xcode 9的一本全面教程,旨在帮助初学者掌握iOS开发的基本技能。这本书通过清晰易懂的讲解和丰富的实践项目,让你逐步深入iOS应用的世界。 首先,PDF格式的完整教程是学习的...

    win7+虚拟机9+mac lion 10.8+XCODE 4.5 安装说明

    这几天安装好了IOS开发软件,所以分享下安装过程。 win7+虚拟机9+mac lion 10.8+XCODE 4.5 安装说明 非常详细 里面包含所有安装软件的下载地址和说明。

    Synchronous requests for Alamofire_Alamofire的同步请求_swift

    iOS 9.0+ / Mac OS X 10.11+ / tvOS 9.0+ / watchOS 2.0+ Xcode 8.0+ Swift 3.0+ Installation For Alamofire 4.0+: pod 'Alamofire-Synchronous', '~&gt; 4.0' For Alamofire 3.0+: pod 'Alamofire-Synchronous',...

Global site tag (gtag.js) - Google Analytics