3.3 swift

2019-07-20 08:14:06 fonx 阅读数 57

每次升级 iOS 版都是虐心的体验。

由于半年没有更新 Xcode,使用旧版 Xcode 编译不给上架了。

SDK Version Issue. This app was built with the iOS 11.4 SDK. All iOS apps submitted to the App Store must be built with the iOS 11 SDK or later, included in Xcode 9 or later. Further, starting March 2019, all iOS apps submitted to the App Store must be built with the iOS 12.1 SDK or later, included in Xcode 10.1 or later.

 

而升级到最新的 Xcode 10,需要升级 macOS 到 mojave,

升级完 mojave 之后,花了一个通宵下载了 Xcode10.2,中间 N 次中断,丫的还不支持断点续传。

升级完 Xcode 之后,又告知必须升级到  Swift 4,而新版的 Xcode 10.2 又关闭了 Swift 3->4 的转换功能,也就是说必须先用旧版本的 Xcode 先转换到 Swift 4 ,才能升级 Xcode ...

好吧,Swift 3 -> 4 都改了这些:

(1)   func  ->   @obj  func

(2)  in sqlitdb.swift,  CInt(params!.count) -> params!.count

(3)  UIColor(colorLiteralRed: Float(xxx)/Float(xxx),green:0.8,blue:0,alpha:1.0)   ->   UIColor(red: CGFloat(Float(xxx)/Float(xxx)),green:0.8,blue:0,alpha:1.0)

2016-12-13 13:49:22 sinat_20037505 阅读数 5659

/**

         数组元素的访问  和在数组中插入或者增加元素

         */

        

        var array1 = ["a", "b", "c"]

        // 不能越界

        print(array1[1])

        

        

        print("------------>")

        // 尾部添加

        array1.append("44")

        print(array1)

        

        print("------------>")

        // 也不可以越界

        array1.insert("yy", at: 0)

        print(array1)


2016-03-15 03:13:00 dazeng1990 阅读数 1440
  • 默认情况下,所有的构造方法都是指定构造函数 Designated
  • convenience 关键字修饰的构造方法就是便利构造函数
  • 便利构造函数具有以下特点:
    • 可以返回 nil
    • 只有便利构造函数中可以调用 self.init()
    • 便利构造函数不能被重写或者 super
/// `便利构造函数`
///
/// - parameter name: 姓名
/// - parameter age:  年龄
///
/// - returns: Person 对象,如果年龄过小或者过大,返回 nil
convenience init?(name: String, age: Int) {
    if age < 20 || age > 100 {
        return nil
    }

    self.init(dict: ["name": name, "age": age])
}

注意:在 Xcode 中,输入 self.init 时没有智能提示

/// 员工类
class Engineer: Person {

    /// 工号
    var no: String?

    convenience init?(name: String, age: Int, no: String) {
        self.init(name: name, age: age)

        self.no = no
    }
}

便利构造函数应用场景

  • 根据给定参数判断是否创建对象,而不像指定构造函数那样必须要实例化一个对象出来
  • 在实际开发中,可以对已有类的构造函数进行扩展,利用便利构造函数,简化对象的创建

构造函数小结

  • 指定构造函数必须调用其直接父类的的指定构造函数(除非没有父类)
  • 便利构造函数必须调用同一类中定义的其他指定构造函数或者用 self. 的方式调用父类的便利构造函数
  • 便利构造函数可以返回 nil
  • 便利构造函数不能被继承
2016-06-04 09:51:38 u013676544 阅读数 836
字典是一种存储多个相同类型的值的容器,就是键值对,跟js中的json一样吧!
Swift的字典使用Dictionary<Key,Value>定义,其中Key是字典中键的数据类型,Value是字典中对应于这些键所存储值的数据类型。
注意:一个字典的Key类型必须遵循Hashable协议,就像前面我们提到的Set的值的类型,也要遵循Hashable协议。

创建一个空字典
1
2
3
var namesOfIntegers = [Int:String]()
namesOfIntegers[16] = "sixteen"
namesOfIntegers = [:]
用字典字面量创建字典
1
2
3
var airports:[String:String] = ["XYZ":"Toronto Pearson","DUB":"Dublin"]
//因为Swift可以推断出类型,所以也可以等价为
var airports = ["XYZ":"Toronto Pearson","DUB":"Dublin"]
访问和修改字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//使用count来获取字典的元素个数
airports.count
//使用isEmpty来判断字典元素个数是否为0
if airports.isEmpty{
 
}
//字典下标语法
airports["LHR"] = "London"  //重新设置新的键值对
airports["LHR"] = "London Heathrow" //修改某个键对应的值
 
//使用updateValue(_:forKey:) ,返回值当前key所对应的旧值或nil,也就是说返回值是一个optional类型的值
if let oldValue = airports.updateValue("Dublin Airport",forKey:"DUB"){
    print("\(oldValue)")
}
 
//同样下标语法来获取某个键对应的值得到的也是optional类型的值
if let airportName = airports["DUB"]{
    print("\(airportName)")
}else{
    print("nil")
}
移除字典中的某个元素
1
2
3
4
5
6
7
8
9
10
airports["APL"] = "Apple Internation"
//通过赋值为nil来移除字典的某个键所对应的元素
airports["APL"] = nil
 
//使用removeValueForKey(_:),返回旧值或nil
if let removedValue = airports.removeValueForKey("DUB"){
    print("\(removedValue)")
}else{
    print("nil")
}
字典遍历
1
2
3
4
5
6
7
8
9
10
11
for (airportCode,airportName) in airports{
    print("\(airportCode):\(airportName)")
}
 
//使用字典的keys,values属性来获取所有的key和value值
for airportCode in airports.keys{
    print("\(airportCode)")
}
for airportName in airports.values{
    print("\(airportName)")
}
用字典的keys,values来创建数组
1
2
3
let airportsCode = [String](airports.keys)
//拥有一定排序能力的keys
let airportsSortCode = [String](airports.keys.sort())

2016-10-15 09:45:08 qq_16437739 阅读数 5659

Swift3.0语法变化

写在前面

首先和大家分享一下学习新语法的技巧:
用Xcode8打开自己的Swift2.3的项目,选择Edit->Convert->To Current Swift Syntax… 让Xcode帮我们把Swift2.3的代码转换为Swift3.0。

这里写图片描述
手动调出Xcode自动转换Swift2.3 到 Swift3.0

弹出语言版本选择界面,选择Covert to Swift3,Next:
这里写图片描述

进入选择模块界面:
这里写图片描述
选择模块界面

建议只选择自己创建的模块,第三方框架的模块最好不要使用Xcode来转换,等待第三方作者更新。

进入转换界面:
这里写图片描述
转换界面
不要着急Save,在这个界面中详细的列出了各个语法具体变化,我们可以利用这个界面来快速学习自己项目中遇到语法变化。

好了,下面给大家分享一下我的遇到的语法变化。

常用类及方法的Swfit风格化

UIColor

将常用的标准颜色写成了只读属性,不再是方法,调用方法改变。
这里写图片描述

Swift 2.3 UIColor

这里写图片描述

Swift 3.0 UIColor

这里写图片描述

Swift 3.0 和 Swift 2.0 写法对比

Any和AnyObject

这两个类型都是Swift中很早就出现的类型,但是我们经常使用AnyObject,很少使用Any。
AnyObject类似于OC中的id类型,表示任意的class的实例对象,但是在Swift中,例如我们常见的String和Array都变为结构体了,而且在Swift3.0中,更多的类型或者枚举被写为结构体了,AnyObject的适用范围变相被削弱了,所以在Swift3.0的API中曾经许多AnyOjbect的类型被替换为Any了。
当然,这对于我们使用这些API没有影响,但是在我们自己定义方法时,如果需要用到AnyObject,就需要认真考虑一下该用AnyObject还是Any了。
这里写图片描述

Swift 3.0 和 Swift 2.0 写法对比

BOOL属性的命名规则

在OC中,官方建议我们将BOOL属性的getter方法命名为isXXX,Swift中由于只是将原有OCUIKit框架进行Swift转换,所以这个规则在之前是Swift中并没有体现。在Swift3.0中,这个规则被再次应用,所有的BOOL类型都重新命名为isXXX,所以以后我们的自定义类中BOOL属性的命名也应体现这个规则。
这里写图片描述

布尔类型的属性get方法改变

Foundation框架部分类名去掉NS前缀

包括:UserDefaults、URL、NotificationCenter、Bundle、Timer、Thread、RunLoop
这里写图片描述

Swift 3.0 和 Swift 2.3 写法对比

常用系统提供单例类的获取方法Swift风格化

这里写图片描述
Swift 3.0 和 Swift 2.3 写法对比

常用结构体的构造方法改变

常用的结构体有:CGSize、CGPoint和CGRect。
这里写图片描述

Swift 3.0 和 Swift 2.3 写法对比

Swift2.3中,使用构造方法和make函数都可以创建;

// Make函数创建
let _ = CGSizeMake(10, 20)
// 构造方法创建
let _ = CGSize(width: 10, height: 20)
Swift3.0中,废弃make函数,只能使用构造方法创建。

// 只能使用构造方法创建
let _ = CGSize(width: 10, height: 20)

转变为结构体的类

在之前的Swift版本中,苹果引入了String、Array和Dictionary这三个结构体来代替OC中的NSString、NSArray和NSDictionary这三个类,当然这三个OC类依然可以使用。但是在平时的开发使用中,Swift的这三个结构体使用起来更方便,大部分情况下效率更高。
在Swift3.0中,苹果又推出了以下新的结构体,原有OC类依然可以使用。并且可以相互转化。
这里写图片描述
新增结构体类型及对应的OC类型

通知的变化

这里写图片描述

Swift 3.0 和 Swift 2.3 写法对比

Swift 3.0 中NSNotification和Notification创建时,通知的name参数类型都变为“Notification.Name”类型,该类型创建比较复杂。

// Swift3.0中的通知
let _ = NSNotification(name: NSNotification.Name(rawValue: “name”), object: nil)
let _ = Notification(name: NSNotification.Name(rawValue: “name”))

UIViewController 返回是否显示状态栏的方法变化

这里写图片描述
控制器方法改为属性

获取string的字符串长度方法的改变

这里写图片描述
获取字符串长度参数改变

获取沙盒指定文件夹路径的方法变化

获取文件路径统一交给FileManager来管理
这里写图片描述

获取沙盒路径参数改变

Swift3.0中GCD语法的改变

Swift3.0中GCD写起来更简洁了。
这里写图片描述
GCD语法改变

延迟执行的代码转换的不够好。应该这样写:

// 延迟执行代码
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5) {
print(“2324”)
}

Swfit的关键字的变化

private和fileprivate

private: 私有属性和方法,仅在当前类中可以访问,不包括分类;
fileprivate: 文件内私有属性和方法,仅在当前文件中可以访问,包括同一个文件中不同的类。

/// 以下所有的类都在同一个文件中
class Test: NSObject {
// 只能在当前大括号内访问
private var value: Int = 0
// 只能在当前文件内访问
fileprivate var value1: Int = 0

// 只能在当前大括号内访问
private func privatePractise() {
value = 1
value1 = 1
fileprivatePractise()
fileprivatePractise1()
print(“privatePractise方法被调用了”)
}
// 只能在当前文件内访问
fileprivate func fileprivatePractise() {
privatePractise()
fileprivatePractise()
fileprivatePractise1()
print(“fileprivatePractise方法被调用了”)
}
}
extension Test {
// 只能在当前大括号内访问
private func privatePractise1() {
value1 = 1
fileprivatePractise()
fileprivatePractise1()
print(“privatePractise方法被调用了”)
}

// 只能在当前文件内访问
fileprivate func fileprivatePractise1() {
privatePractise1()
fileprivatePractise()
print(“fileprivatePractise方法被调用了”)
}
}
class Test2: NSObject {
func test() {
let t = Test()
t.value1 = 0
t.fileprivatePractise()
t.fileprivatePractise1()
}
}

public和open

在Swift2.3中,pubic有两层含义:

  1. 这个元素可以在其他作用域被访问
  2. 这个元素可以在其他作用域被继承或者override

继承是一件危险的事情。尤其对于一个framework或者module的设计者而言。在自身的module内,类或者属性对于作者而言是清晰的,能否被继承或者override都是可控的。但是对于使用它的人,作者有时会希望传达出这个类或者属性不应该被继承或者修改。这个对应的就是 final。

final的问题在于在标记之后,在任何地方都不能override。而对于lib的设计者而言,希望得到的是在module内可以被override,在被import到其他地方后其他用户使用的时候不能被override。

这就是 open产生的初衷。通过open和public标记区别一个元素在其他module中是只能被访问还是可以被override。

在Swift3.0中

  • public表示当前类、属性或者方法只能在当前module内被继承或者override,在当前module意外只能被访问;
  • open表示当前类、属性或者方法可以在任何地方被继承或者override;
  • final是一个辅助修饰词,表示当前类、属性或者方法在任何地方都只能被访问,不能被继承或者override;
  • internal表示默认级别。

/// ModuleA:
import UIKit
/// 这个类在ModuleA的范围外是不能被继承的,只能被访问
public class NonSubclassableParentClass: NSObject {
// 这个方法在ModuleA的范围外只能被访问,不能被override
public func test() {
print(“test”)
}
//这是错误的写法,因为class已经不能被集成,所以她的方法的访问权限不能大于类的访问权限
open func bar() {
print(“bar”)
}
// 这个方法在任何地方都只能被访问,不能被override
public final func baz() {
print(“baz”)
}
}
/// 在ModuleA的范围外可以被继承
open class SubclassableParentClass: NSObject {
// 这个属性在ModuleA的范围外只能被访问,不能被override
public var size: Int = 0
// 这个方法在ModuleA的范围外只能被访问,不能被override
public func foo() {
print(“foo”)
}
// 这个方法在任何地方都可以被override
open func baz() {
print(“baz”)
}
// 这个方法在任何地方都只能被访问,不能被override
public final func bar() {
print(“bar”)
}
}
/// 这个类在任何地方都不能被继承
public final class FinalClass {
}

总结

Swfit3.0中,访问控制权限由高到低依次为:open、public、internal(默认)、fileprivate,private。

Swift3.0中if…where和guard…where的变化

Swift3.0中对where关键字的使用场景进行了一些调整,在Swift2.3中,我们常这样写:

// Swift2.3
var value: Int?
var num: Int?

if let v = value, n = num where v > n {
print(“value > num”)
}

value = 1
num = 2

guard let v = value, n = num where v > n else {
print(“value < num”)
return
}
在Swift3.0中,应该这样实现:

// Swift3.0
var value: Int?
var num: Int?

if let v = value, let n = num, v > n {
print(“value > num”)
}

value = 1
num = 2

guard let v = value, let n = num, v > n else {
print(“value < num”)
return
}

Swift3.0中枚举的变化

在Swift2.3中,官方使用的枚举值首字母使用大写,在Swift3.0中,统一将官方使用的枚举值首字母改为了小写。虽然自定义的枚举中枚举值首字母依然可以使用大写,但是为了和官方风格保持一致,建议枚举值首字母使用小写。

/// 这种写法是正确的(与官方风格一致,推荐使用)
enum Direction: String {
case east = “east”
case south = “south”
case west = “west”
case north = “north”
}

/// 这种写法也是正确的(与官方风格不一致,不推荐使用)
enum Sex: Int {
case Man = 0
case Woman = 1
case Other = 2
}

Swift3.0中方法名的Swift风格化

在Swift的方法命名规则中,参数有两个名称,一个内部名,一个外部名。当参数有外部名时,方法调用时只显示外部名,若无外部名,则默认外部名和内部名相同。
这里写图片描述
外部名和内部名

在Swift2.3中,第一个参数若没有外部名,则调用时候常省略。对于常用的UIKit和Foundation框架来说,Swift2.3中的方法名称依然是OC语言的风格。
这里写图片描述

Swift2.3 方法名称风格

在Swift3.0中,第一个参数若没有外部名,则调用时显示内部名,不省略。同时将常用的UIKit和Foundation框架的方法名进行了Swift风格化,使方法调用时更简洁清晰。
这里写图片描述

Swift3.0 方法名称风格

两种风格方法调用对比:
这里写图片描述
dismiss方法swift风格化

建议以后自定义方法时,风格尽量和Swift3.0保持一致。
在Swift3.0 编译器环境下两种风格对比:
这里写图片描述

自定义方法两种风格对比

Swift3.0中selecter的Swift风格化

在Swift2.2中,当我们为一个按钮添加点击事件时常常这样写:
这里写图片描述

Swift 2.3 中 Selector写法

在Swift2.2更新到Swift2.3后可以看到警告告诉我们这是一个OC风格的写法,建议改为Swift风格的写法。
在Swift3.0中两种写法依然都可以使用,但是建议统一写为Swift风格的,因为你不知道什么时候OC风格的就不被允许了。
这里写图片描述
Swift 3.0 中 Selector写法
运算符的变化

  1. Swift3.0中运算符的左右两边必须不能为optional。
  2. ++和–是继承自C语言中的运算符,在Swift3.0中被移除,建议使用 x += 1来代替。
    这里写图片描述

文/光无影(简书作者)
原文链接:http://www.jianshu.com/p/460b5424942a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。