2019-03-27 13:35:40 weiwandaixu_ 阅读数 2041

Xcode10.2, swift5.0

Undefined symbols for architecture x86_64:
"_swift_getFieldAt", referenced from:
HandyJSON.Metadata.Class._propertyDescriptionsAndStartPoint() -> ([HandyJSON.Property.Description], Swift.Int32?)? in Metadata.o
HandyJSON.Metadata.Struct.propertyDescriptions() -> [HandyJSON.Property.Description]? in Metadata.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

 

更改 podfile

pod 'HandyJSON', '5.0.0-beta'

如果不行的话 更新本地cocoapods的spec资源配置信息。

pod repo update

 

2019-02-13 18:03:05 weixin_40840896 阅读数 559

时隔半年之久,项目缠身,没能督促自己跟进Swift,一转眼已是5.0,带着问题来学习吧。
The Swift Programming Language(Swift 5.0)

这里是OC与Swift对比之下提出的问题,之后会陆续找到答案的:

文档里说,Swift通过采用现代编程模式来定义大类常见的编程错误:

  • 变量在使用之前要被初始化 

    Q:OC有这个特性吗?
    A:OC没有要求,使用之前一定要初始化.不过个人建议先初始化后再使用,初始化后,指针所指向的空间有了,对象也存在了.
    如果想要了解变量初始化的意义,可以参考文章:iOS中定义变量是否初始化的区别
  • 检查数组是否越界
  • 检查整数是否溢出

    Q:OC是否可以编译时检查数组是否越界?
    A:OC是动态语言,只会在运行时才知道数组是否越界,没有预知能力,所以swift更安全
  • 可选值(Optionals) 确保nil 明确地被处理过

    Q: OC可以处理nil值吗?
    A:若不做任何保护代码判断,OC 是没有能力自行判断的
  • 自动管理内存

    Q:OC的内存自动管理机制和Swift有什么不同吗?
    A:Swift使用自动引用计数(ARC)来简化内存管理,与OC一致
  • 错误处理允许从异常失败中控制恢复。

    Q: OC可以做到吗?
    A:目前还没听说,异常失败后就app就退出了,需要重启,Swift如何做到,有待继续学习.

 

 

参考文章:iOS中定义变量是否初始化的区别

2019-12-17 15:09:02 jia12216 阅读数 32

作为老iOS程序猿,受不了xid和storyboard页面的大文件,布局麻烦,更喜欢纯代码页面简单灵活,动态修改。开始学习swift了,还是喜欢纯代码页面。并且由于我们程序猿的强迫症,也想第一个页面也是纯代码页面。
经过实践,通过XCode11.2.1创建的swift工程,Launch Screen File不能是原来的LaunchImage.launchimage。那只好采用默认的LaunchScreen.storyboard(LaunchScreen.xib应该也可以)。
想做成首页是纯页面:
1.删除Main.storyboard,SceneDelegate.swift和ViewController.swift文件。
2.在Info.plist文件中删除Main storyboard file base name属性和Application Scene Manifest属性。
3.创建简单首页:HomeViewController.swift。
4.在AppDelegate.swift文件的didFinishLaunchingWithOptions函数中增加页面代码:

        self.window = UIWindow.init(frame: UIScreen.main.bounds)

        let login = UINavigationController.init(rootViewController: HomeViewController())

        self.window?.rootViewController = login
        self.window?.backgroundColor = UIColor.white

        self.window?.makeKeyAndVisible()

5.注释下面的函数:

//    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
//        // Called when a new scene session is being created.
//        // Use this method to select a configuration to create the new scene with.
//        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
//    }
//
//    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
//        // Called when the user discards a scene session.
//        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
//        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
//    }

我就是因为没有把他们报错,瞎折腾了好久。
6.当然在Targets->Build Settings->Swift Language Version设置为Swift5。
工程代码

2018-01-21 17:18:47 liushuo19920327 阅读数 2785

自Swift 3.0 以来,语言已经比较成熟,用Swift语言来开发iOS App 的开发者越来越多,那么一份权威而全面的规范就很有必要了。苹果官方的文档有时间大家还是多看看,笔者参考官方文档和各路大神的经验,写下了一份基于Swift 4.0 的编码规范,并会持续更新,欢迎大家补充指正。

1. 编码格式

1.1 使用二元运算符(+, -,==, 或->)的前后都需要添加空格

let value = 1 + 2

1.2 在逗号后面加一个空格

let titleArray = [1, 2, 3, 4, 5]

1.3 方法的左大括号不要另起,并和方法名之间留有空格,注释空格

// function Define
func myFunction {
    // 处理
}

1.4 判断语句不用加括号

if typeValue == 1 {
    // 处理
}

1.5 尽量不使用self. 除非方法参数与属性同名

func setPerson(name: String, pAge: Int) {
    self.name = name
    age = pAge
}

1.6 在访问枚举类型时,使用更简洁的点语法

enum Direction {
    case north
    case south
    case east
    case west
}
let currentDirection = .west

1.7 添加有必要的注释,尽可能使用Xcode注释快捷键(⌘⌥/)

/// <#Description#>
///
/// - Parameters:
///   - tableView: <#tableView description#>
///   - section: <#section description#>
/// - Returns: <#return value description#>
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return dataList.count
}

1.8 使用 // MARK: -,按功能、协议、代理等分组

// MARK: - UITableViewDelegate

// MARK: - Action

// MARK: - Request

1.9 协议一致性:当对象要实现协议一致性时,推荐使用 extension 隔离协议中的方法集,这样让相关方法和协议集中在一起,方便归类和查找

// MARK: - UICollectionViewDelegate, UICollectionViewDataSource
extension XMHomeViewController: UICollectionViewDelegate, UICollectionViewDataSource {
	// 代理方法
}

// MARK: - HttpsRequest
extension XMHomeViewController {
	// 网络请求方法
}

1.10 当对外接口不兼容时,使用@available(iOS x.0, *) 标明接口适配的起始系统版本号

@available(iOS 8.0, *)
func myFunction() {
    //
}

2. 命名规范

2.1 常量,变量,函数,方法的命名规则使用小驼峰规则,首字母小写,类型名使用大驼峰规则,首字母大写。

class MyClass: class {
    let myImageView: UIImageView
    let myName: String
}

2.2 当命名里出现缩写词时,缩写词要么全部大写,要么全部小写,以首字母大小写为准

let htmlString = "https://www.baidu.com"
let urlString:  URLString
let userID:  UserID

class HTMLModel {
    //
}

2.3 bool类型命名时,使用is作为前缀

var isMine: Bool = false

2.4 Swift中类别(类,结构体)在编译时会把模块设置为默认的命名空间,所以不用为了区分类别而添加前缀,比如XYHomeViewController,但是为了和引用的第三方库作区分,建议可以继续使用前缀,以作为规范化处理,结构更清晰。

2.5 懒加载用来细致地控制对象的生命周期,这对于想实现延迟加载视图的UIViewController特别有用

// MARK: - 懒加载
private lazy var tableView: UITableView = {
    let tableView = UITableView.init(frame: CGRect.zero, style: .plain)
    tableView.separatorStyle = .none
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 200
    tableView.dataSource = self
    tableView.delegate = self
    tableView.register(UINib(nibName: homeListCell, bundle: nil), forCellReuseIdentifier: homeListCell)
    return tableView
}()

2.6 当函数的第一个参数构成整个语句的介词时(如,at, by, for, in, to, with 等),为第一个参数添加介词参数标签

func login(with username: String?, password: String?) {
	//
}

3. 语法规范

3.1 可选类型拆包取值时,使用if let 判断

if let data = result.data {
    //
}

3.2 多个可选类型拆包取值时,将多个if let 判断合并

if let name = person.name, let age = person.age {
    //
}

3.3 尽量不要使用 as! 或 try!,对于可选类型Optional多使用as?,?? 可以给变量设置默认值

// 使用if let as?判断
if let name = person.name as? String {
    //
}
// 给name变量设置默认值
var name = person.name ?? ""

3.4 数组和字典变量定义时需要标明泛型类型,并使用更简洁清晰的语法

var names: [String] = []
var values: [String: Int] = [:]
var person: [String: Any] = [:]

3.5 常量定义,建议尽可能定义在类型里面,避免污染全局命名空间,如果是其他地方有可能复用的cell可以定义在类型外面

static let homeListCell = "HomeListCell"

class HomeListCell: UITableViewCell {
    static let kHomeCellHeight = 80.0
    //
}

3.6 当方法最后一个参数是Closure类型,调用时建议使用尾随闭包语法

UIView.animateWithDuration(1.0) {
     self.myView.alpha=0
}

3.8 最短路径规则:当编码遇到条件判断时,左边的距离是黄金路径或幸福路径,因为路径越短,速度越快。guard 就为此而生的。

func login(with username: String?, password: String?) throws -> LoginError {
  guard let username = username else { 
    throw .noUsername 
  }
  guard let password = password else { 
    throw .noPassword
  }
  // 处理登录
}

3.9 循环遍历使用for-in表达式

// 循环
for _ in 0..<list.count {
  print("items")
}
// 遍历
for(index, person) in personList.enumerate() {
    print("\(person)is at position #\(index)")
}
// 间隔2位循环
for index in 0.stride(from: 0, to: items.count, by: 2) {
  print(index)
}
// 翻转
for index in (0...3).reverse() {
    print(index)
}

4. Swift 4.2 新特性

4.1 CaseIterable协议:定义的枚举遵循CaseIterable协议后,编译时Swift 会自动合成一个allCases属性,是包含枚举的所有case项的数组

enum NetState: CaseIterable {
    case wifi
    case hotWifi
    case mobile
    case none
}
for item in NetState.allCases {
    print(item)
}

4.2 #warning 主要用于标记一些工作还没有完成或者需要完善,Xcode 会发出一个警告;#error 标记错误,Xcode 会发出一个编译错误这样你的代码就完全不能编译

#warning("列表刷新需要优化")

#if os(macOS)
#error("MyLibrary is not supported on macOS.")
#endif

4.3 新增 allSatisfy():一种检查序列中的所有元素是否满足条件的新方法

// 判断数组的所有元素是否全部大于80
let scores = [86, 88, 95, 92]
// 返回一个BOOL
let passed = scores.allSatisfy({ $0 > 80 })
print(passed)
// 输出:true

4.4 新增 last(where:) 和 lastIndex(where:) 方法来获取数组中满足条件的最后的元素和索引值

let a = [10, 20, 30, 40, 50, 30, 20]
// 获取满足条件的元素
print(a.last(where: { $0 > 30 }))   //50
// 获取满足条件的元素的索引
print(a.lastIndex(where: { $0 > 25 }))   //4

4.5 新增 random() 随机数方法来生成一个随机数, 只需提供一个随机数范围即可

// 随机数
let ranInt = Int.random(in: 0..<10)
let ranFloat = Float.random(in: 0..<10)

let a = [10, 20, 30, 40, 50, 30, 20]
// 对数组重新洗牌, 重新随机排序返回一个数组
let shuffled = a.shuffled()
// 获取数组中的一个随机元素,空数组返回nil
let random = a.randomElement() 

4.6 新增 removeAll(where:) 方法,高效地执行根据条件删除操作

var names = ["John", "Michael", "Graham", "Andy", "Eric", "Andy"]
names.removeAll { $0.hasPrefix("Andy") }
print(names)
// 输出:["John", "Michael", "Graham", "Eric"]

5. Swift 5.0 新特性

5.1 ABI(Application Binary Interface)稳定:ABI定义了函数如何调用,数据如何在内存中呈现,元数据在哪里,以及如何访问等底层交互。之前的Swift版本中ABI还没稳定,所以每一个APP,都自己包含它Swift版本所对应的Swift Dynamic Library。ABI稳定之后,Swift动态库将包含在iOS操作系统里,它将兼容每一个Swift版本。

5.2 新增 @dynamicCallable 为Swift添加了一个新属性,允许使用一个简单的语法糖像调用函数一样调用命名类型,需要实现下面两个方法中的一个:

func dynamicallyCall(withArguments args: [Int]) -> Double
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double
// 定义方式
@dynamicCallable
struct RandomNumberGenerator {
    func dynamicallyCall(withArguments args: [Int]) -> Double {
        let numberOfZeroes = Double(args.first ?? 0)
        let maximum = pow(10, numberOfZeroes)
        return Double.random(in: 0...maximum)
    }
}
// 调用方式
let random = RandomNumberGenerator()
let num = random(2)
// random(2)等同于random.dynamicallyCall(withArguments: [2])

5.3 修改:定义一个带有(可变参数 => 数组参数)的枚举

enum X {
    case foo(bar: [Int]) 
} 
func baz() -> X {
    return .foo(bar: [0, 1, 2, 3]) 
} 

5.4 新增创建原始字符串的功能,以及创建多行字符串

let quote = "Alice: \"How long is forever?\" White Rabbit: \"Sometimes, just one second.\""
let rain = #"The "rain" in "Spain" falls mainly on the Spaniards."#
let multiline = #"""
    The answer to life,
    and everything is \#(answer).
    """#

5.5 Swift 5中无论有多少个嵌套的可选,最后返回值永远只是一个可选值,使用try?

// 类型: let messages: String?
let messages = try? user?.getMessages()
print(messages ?? "")

5.6 新增了一个函数 count(where:),可以获取数组中符合条件的元素的个数

let arr = [1, 28, 3, 40, 5, 6]
let count = arr.count(where: { $0 > 10 })
print(count)  // 2

5.7 在 Swift4.x 的版本中有两个函数 compactMap 和 mapValues
compactMap: 返回一个操作后得到的新的数组, 类似flatMap
mapValues: 对字典的value值执行操作, 返回改变value后的新的字典
Swift5.0 新增了一个函数 compactMapValues 返回一个对value操作后的新字典, 并且自动过滤不符合条件的键值对

let guys = [
    "Hudson": "30",
    "Clarke": "40",
    "Robinson": "50",
    "Hartis": "DNF"
]
let comMap = guys.compactMapValues({ Int($0) + 3 })
print(comMap)
// ["Clarke": 43, "Robinson": 53, "Hudson": 33]
2019-01-28 15:41:57 ShmilyCoder 阅读数 4043

Swift

  • 原文博客地址: Swift 5.0新特性更新
  • 期待已久的Swift 5.0终于来啦, Swift 5.0Swift中最备受关注的一个版本, 传说中ABI稳定的版本
  • 随着Xcode Bate 10.2的发布, Swift 5.0也发布了测试版, 相信也带来了很多优化和改进
  • 下面运行环境都是在Xcode Bate 10.2环境中进行的

新特性

dynamicCallable

  • SE-0216
  • @dynamicCallableSwift添加了一个新属性, 允许使用一个简单的语法糖调用函数一样调用命名类型
  • 如果需要添加@dynamicCallable属性, 就必须要实现以下方法中的一个或者两个
func dynamicallyCall(withArguments args: [Int]) -> Double

func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double
  • 注意点:
  • 除了接受各种输入外,您还可以为各种输出提供多个重载, 自定义返回值, 可以是String, Int等等…
  • KeyValuePairs的使用和介绍, 没有使用过的可参考

下面看一个例子, RandomNumberGenerator生成一个随机数

Swift 5.0之前的定义和调用方式

// 定义方式
struct RandomNumberGenerator {
    func generate(numberOfZeroes: Int) -> Double {
        let maximum = pow(10, Double(numberOfZeroes))
        return Double.random(in: 0...maximum)
    }
}


// 调用方式
let random = RandomNumberGenerator()
let num = random.generate(numberOfZeroes: 2)
print(num)

Swift 5.0使用@dynamicCallable属性

// 定义方式
@dynamicCallable
struct RandomNumberGenerator {
    func dynamicallyCall(withArguments args: [Int]) -> Double {
        let numberOfZeroes = Double(args.first ?? 0)
        let maximum = pow(10, numberOfZeroes)
        return Double.random(in: 0...maximum)
    }
}


// 调用方式
let random = RandomNumberGenerator()
let num = random(2)
// random(2)等同于random.dynamicallyCall(withArguments: [2])
print(num)
  • @dynamicCallable使用注意事项
  • 可以将它应用于结构,枚举,类和协议。
  • 如果你实现withKeywordArguments:并且没有实现withArguments:,你仍然可以在没有参数标签的情况下调用
  • 如果你的实现withKeywordArguments:withArguments:时标记为throw,则调用该类型也将被抛出throw
  • 扩展名无法添加@dynamicCallable,只能添加到主要类型上
  • 仍然可以为你定义的类型添加其他方法和属性,并且能够正常使用

WritableKeyPath

  • SE-0227
  • 添加引用标识键路径的功能,该路径指的是应用它的整个输入值
  • Swift中的每个值都有一个特殊的伪属性.self,它指的是整个值
let id = \Int.self  
var x = 1
print(id)   ////Swift.WritableKeyPath<Swift.Int, Swift.Int>
x.self = 2
print(x)   //2
print(x.self)  //2

print(x[keyPath: id])  //2
x[keyPath: id] = 3
print(x[keyPath: id])  //3

可选参数

Swift 5之前,可以编写一个带有可变参数的枚举, 但是在Swift 5开始, 调用时会报错, 如下

enum X {
    // 此处定义切没有调用时不会报错
    case foo(bar: Int...) 
}

func baz() -> X {
    // 此处调用时会报错
    return .foo(bar: 0, 1, 2, 3) 
} 

Swift 5之后, 上述定义改成数组参数, 而不是可变参数, 如下

enum X {
    case foo(bar: [Int]) 
} 

func baz() -> X {
    return .foo(bar: [0, 1, 2, 3]) 
} 

Raw Strings

\处理

  • SE-0200增加了创建原始字符串的功能,其中反斜杠和引号被解释为文字符号,而不是转义字符或字符串终止符
  • 单行字符串文字可以用反斜杠填充, 以保证原字符串, 否则会报错
// 文字引用类型
// 错误写法
let quote = "Alice: "How long is forever?" White Rabbit: "Sometimes, just one second.""
// 正确写法
let quote1 = "Alice: \"How long is forever?\" White Rabbit: \"Sometimes, just one second.\""


// 正则表法式类型
// 错误写法
let ucCaseCheck = "enum\s+.+\{.*case\s+[:upper:]"
// 正确写法
let ucCaseCheck = "enum\\s+.+\\{.*case\\s+[:upper:]"

#处理

  • 要使用原始字符串, 可使用#将字符串包裹起来
  • #字符串开头和结尾的符号成为字符串分隔符的一部分,因此如下Swift理解“rain”“Spain”周围的独立引号应该被视为文字引号而不是结束字符串
  • 原始字符串也允许使用反斜杠, 但是将反斜杠视为字符串中的文字字符,而不是转义字符
let rain = #"The "rain" in "Spain" falls mainly on the Spaniards."#

let keypaths = #"Swift keypaths such as \Person.name hold uninvoked references to properties."#

let answer = 42
let dontpanic = #"The answer to life, the universe, and everything is \#(answer)."#

注意: 上面使用\#(answer)引用变量而不是\(answer), 因为在用#包裹的字符串中反斜杠将会被失败别为文字字符而不是转义字符, 所以必须额外的添加#

##处理

  • 在字符串的开头和结尾使用#处理, 在字符串中可以使用反斜杠等特殊字符, 那如果字符串中需要使用#, 又该如何处理??
  • 使用#包裹字符串, 默认会以#为字符串的结束符号, #后面的文字将不再处理, 在这种情况下, 我们会使用##处理
  • 注意: 字符串的开头和结尾的标识必须一样
let str = ##"My dog said "woof"#gooddog"##

多行字符串

原始字符串与Swift的多行字符串系统完全兼容 - 只需用于#"""启动,然后"""#结束

let multiline = #"""
    The answer to life,
    the universe,
    and everything is \#(answer).
    """#

try?嵌套

先看下面代码

struct User {
    var id: Int

    init?(id: Int) {
        if id < 1 {
            return nil
        }

        self.id = id
    }

    func getMessages() throws -> String {
        // complicated code here
        return "No messages"
    }
}

Swift4.2及其之前的版本中

let user = User(id: 1)
// 这里得到的message的类型是: let messages: String??
let messages = try? user?.getMessages()

// 如果我们想得到非可选值就需要
print((messages ?? "") ?? "")
// 或者多次强解, 当然不建议强解写法
print(messages!!)
  • Swift4.2及其之前的版本中, 上面返回的是一个2层嵌套的可选值, 如果有多层嵌套处理起来也是相当更麻烦的
  • Swift 5中就完美的解决了这个问题, 如果当前值是可选的, 那么try?将不会将值包装在可选值中, 因此最终结果只是一个String?
  • 因此在Swift 5中无论有多少可嵌套的可选最后, 返回值永远只是一个可选值
  • 同样,如果你使用了可选的链接as?,你仍然只有一个级别的可选性
let user = User(id: 1)
// 类型: let messages: String?
let messages = try? user?.getMessages()

print(messages ?? "")

isMultiple

  • SE-0225为整数类型添加了一个方法isMultiple
  • 该方法可以检查一个证书是否为另一个整数的倍数
let rowNumber = 4

if rowNumber.isMultiple(of: 2) {
    print("Even")
} else {
    print("Odd")
}

// 该方法等效于
if rowNumber % 2 == 0 {}

count

  • SE-0220
  • Swift之前的版本中, 有一个函数filter可以过滤出数组中符合条件的的元素, 组成一个新的数组, 详细使用可参考Swift函数式编程之高级用法
  • Swift 5中新增了一个函数count(where:), 可以获取数组中符合条件的元素的个数
let arr = [1, 2, 34, 5, 6, 7, 8, 12, 45, 6, 9]

let filter = arr.filter({ $0 > 10 })
print(filter)  //[34, 12, 45]

let count = arr.count(where: { $0 > 10 })
print(count)  // 3

compactMapValues

  • Swift4.x的版本有两个函数compactMapmapValues
  • compactMap: 返回一个操作后得到的新的数组, 类似flatMap
  • mapValues: 字典中的函数, 对字典的value值执行操作, 返回改变value后的新的字典
let times = [
    "first": 2,
    "second": 43,
    "three": 12,
    "four": 3
]

let compact = times.compactMap({ $0.value > 10 })
print(compact)
// [true, false, true, false]

let mapValues = times.mapValues({ $0 + 2 })
print(mapValues)
// ["second": 45, "first": 4, "three": 14, "four": 5]
  • SE-0218Swift 5中新增了一个函数compactMapValues
  • compactMapValues是将上述两个方法的功能合并在一起, 返回一个对value操作后的新字典, 并且自动过滤不符合条件的键值对
let times1 = [
    "Hudson": "38",
    "Clarke": "42",
    "Robinson": "35",
    "Hartis": "DNF"
]

let comMap2 = times1.compactMapValues({ Int($0) })
print(comMap2)
// ["Clarke": 42, "Robinson": 35, "Hudson": 38]

SubSequence

  • Sequence协议不再具有SubSequence关联类型。先前返回SubSequenceSequence方法现在会返回具体类型
  • 使用SubSequenceSequence扩展应该修改为类似地使用具体类型,或者修改为Collection的扩展,在CollectionSubSequence仍然可用
// swift 5不在支持
extension Sequence {
    func dropTwo() -> SubSequence {
        return self.dropFirst(2)
    }
}


// 建议改为
extension Sequence {
    func dropTwo() -> DropFirstSequence<Self> { 
        return self.dropFirst(2)
    }
}

// 或者
extension Collection {
    func dropTwo() -> SubSequence {
        return self.dropFirst(2)
    }
}

其他相关更新

SE-0214

DictionaryLiteral类型重命名为KeyValuePairs

SE-0238

  • 在使用Swift 5软件包管理器时,Targets可以声明一些常用的针对特定目标的build settings设置
  • 新设置也可以基于平台和构建配置进行条件化处理。包含的构建设置支持SwiftC语言定义,C语言头文件搜索路径,链接库和链接框架

SE- 0236

  • 在使用Swift 5时, 可以自定义所支持的最低版本号, 如果该项目的依赖包所支持的最低版本大于项目的最低版本号, 则项目会报错

SR-695

Swift 5中不再支持返回Self的类方法

// 不在支持
class Base { 
    class func factory() -> Self { /*...*/ }
} 

SR-631

不同文件中的扩展名无法相互识别

class FirstClass { }

extension FirstClass {
    class SecondClass { }
}

// 这里将会报错: "SecondClass is not a member type of FirstClass"
extension FirstClass.SecondClass { 
    class ThirdClass { }
}

SR-7251

Swift 5中, 在所声明的类里面, 所声明的变量名不能和类名一样

struct S {}
extension S {
  static var i: Int { return 0 }
  struct i {} // error: “i”的声明无效
}

// 下面的方式是没有问题的
struct S1<T> {}
extension S1 {
  static var i: Int { return 0 }
  struct i {} // This is fine!
}

参考文献


[swift]5.0控制语句

阅读数 406

没有更多推荐了,返回首页