• 因为xcode9同时支持Swift4Swift3.2所以在升级Swift4的时候心没有那么的痛,在转换成Swift4时错误集中在添加@objc上,如果项目是OC和Swift共存的项目,那么添加@objc会让你加到怀疑人生。 @objc 1、在Swift4中,OC...

    前言

    因为xcode9同时支持Swift4和Swift3.2所以在升级Swift4的时候心没有那么的痛,在转换成Swift4时错误集中在添加@objc上,如果项目是OC和Swift共存的项目,那么添加@objc会让你加到怀疑人生。

    @objc

    1、在Swift4中,OC和Swift共存的项目不再无脑将Swift的Public属性和方法提供给OC,除非Swift中的方法和属性用@objc标记,这样就减少了一些代码的生成从而减少了包的大小。build之后我们是纯swift项目所以大部分是在选择器调用的方法前面也要添加@objc
    2、我们的项目是Swift的项目所以build保存很快就修改完成,Run起来后如期的Crash了。这个是因为我们的JSON转Model是使用的OC版的Mantle和SwiftJSON进行的解析,那么就要在所有的Model属性前面添加@objc,不然Mantle在获取类属性类型的时候是空的。看到这个时候内心是崩溃和拒绝升级Swift4的,所以我们选择舍弃Mantle使用Codable。

    Codable( 官方文档

    1、在OC中JSON转Model只能转化为对象类型,在Codable支持JSON转为常规类型。而遇到的更多的是将数据模型中的NSNumber改为Int或者Double,这是因为NSNumber是OC的类型不遵守Codable的。
    2、有时候我们会在Model中添加一些JSON串没有的字段进行逻辑处理,类似

    struct A: Codable{
    	var a: Int? 
    	var isSelect: Bool = false
    }
    复制代码

    因为"isSelect"是为了逻辑处理在JSON串中并不能找到相应的字段,这个时候就会报出数据丢失的错误,而我们只需要将“isSelect”改成可选就可以了。

    stuct A: Codable {
    	var a: Int?
    	var isSelect: Bool?
    }
    复制代码

    在这次升级中主要是在改这OC调用Swift添加@objc的问题和将数据解析改成Codable。还有一些错误是因为使用Mantle转JSON串出现的问题只要使用JSONEncode,还有会多出字符串长度判断使用characters的警告删除它就OK了。

    平常使用泛型一个很烦的操作

    我定义一个带有泛型的方法

    private func getData<T>(a: T) {
    
    }
    复制代码

    直接调用

    self.getData<A>(a)
    复制代码

    因为不知道泛型的类型而出现

    Cannot explicitly specialize a generic function
    复制代码

    的错误, 如果不指定类型

    self.getData(a)
    复制代码

    会出现下面的额错误

    Generic parameter 'Element' could not be inferred
    复制代码

    只能在使用时进行一次强转

    self.getData(a as A)
    复制代码

    就是让Xcode推断出他的类型而不是你告诉他这个泛型是什么类型,这就很烦。


    感谢观赏

    展开全文
  • 苹果的swiftAPI更新很快,现在已经升级到swift4,在我做API适配的时候发现Swift4对String的操作简化了很多,所以写一篇文章总结一下,希望能够帮助到有需要的人。 在Swift4之前使用String的字符集需要使用String....
    苹果的swiftAPI更新很快,现在已经升级到swift4,在我做API适配的时候发现Swift4对String的操作简化了很多,所以写一篇文章总结一下,希望能够帮助到有需要的人。
    
    在Swift4之前使用String的字符集需要使用String.characters来获取,如代码
    
    
    var str1 = "What are doing?"
    //Swift3
    for c in str1.characters {
        print(c)
    }
    
    //swift4
    for c in str1 {
        print(c)
    }
    
    //通过两种版本代码对比发现Swift4比Swift3代码简洁的多。
    

    Swift3获取字符串的字符数(长度)是String.characters.count,在Swift4中直接String.count就行了,代码对比如下
    //Swift3
    let length = str1.characters.count
    
    //Swift4
    let length = str1.count
    
    当然如果想要获取特定字符集的长度还是可以用到下面这种写法
    let length = str.utf8.count
    

    当然在swift4之后字符串截取的api变化也很大,之前的截取方法都被废弃掉了,下面我们使用代码来说明。
    let template = "<<<Hello>>>"
    let indexStartOfText = template.index(template.startIndex, offsetBy: 3)
    let indexEndOfText = template.index(template.endIndex, offsetBy: -3)
    
    // Swift4的写法
    let substring1 = template[indexStartOfText...]  // "Hello>>>"
    
    // Swift3的接口已经被废弃,代码如下
    // let substring1 = template.substring(from: indexStartOfText)
    
    ///截取到某个位置
    // Swift4
    let substring2 = template[..<indexEndOfText]    // "<<<Hello"
    
    // Swift3的接口已被废弃
    // let substring2 = template.substring(to: indexEndOfText)
    
    //截取到某个区间
    / Swift4
    let substring3 = template[indexStartOfText..<indexEndOfText] // "Hello"
    
    // Swift3的接口在swift4中已被废弃
    // let substring3 = template.substring(with: indexStartOfText..<indexEndOfText)
    
    //在最后把截取得到的字符串需要转换回String
    let strNew = String(subString)
    
    如果还是习惯以前subString的写法也可以像下边这样写
    let digits = "0123456789"
    let index4 = digits.index(digits.startIndex, offsetBy: 4)
    
    // The first of each of these examples is preferred
    digits[...index4]              // "01234"
    digits.prefix(through: index4)  
    
    digits[..<index4]              // "0123"
    digits.prefix(upTo: index4)     
    
    digits[index4...]              // "456789"
    digits.suffix(from: index4)
    
    //在写截取区间值的时候一定注意开区间和闭区间的事情,他们最后得到的结果不同
    


    查看原文:https://www.liuandy.cn/ios/2017/12/27/2170.html
    展开全文
  • Swift【App版本更新

    2017-11-08 15:03:29
    Swift有对应的版本更新库(Siren),有需要的可以参考和使用。 iOS开发中,有时会有这种需求,在AppStore上出现新版本时,应用内弹窗提示用户更新.自动提示更新的实现方案分为两种: 第一种,自己...
    Swift有对应的版本更新库(Siren),有需要的可以参考和使用。

    iOS开发中,有时会有这种需求,在AppStore上出现新版本时,应用内弹窗提示用户更新.自动提示更新的实现方案分为两种:

    第一种,自己服务器提供一个接口,通过请求,获取app的相关的版本信息,如:是否需要更新,以及更新的地址等信息
    第二种,就是利用苹果的appstore 提供的相关api进行查询更新.http://itunes.apple.com/cn/lookup?id=你的APPId

    采用方案1,实现逻辑:

    1: 向自己服务器请求当前版本信息
    2: 和App当前版本进行比较,如果返回的版本比当前本地版本新,弹窗并显示更新日志,根据点击的按钮,控制用户跳转到AppStore更新

    简单实现
    效果图:



    具体代码实现

    [javascript] view plain copy
    1. struct VersionInfo {  
    2.     var url: String        //下载应用URL  
    3.     var title: String       //title  
    4.     var message: String       //提示内容  
    5.     var must_update: Bool  //是否强制更新  
    6.     var version: String     //版本  
    7. }  
    8.       
    9. class VersionManager: NSObject {  
    10.       
    11.     //本地版本  
    12.    private static func localVersion() -> String? {  
    13.         return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String  
    14.     }  
    15.       
    16.     static func versionUpdate() {  
    17.         //1 请求服务端数据,并进行解析,得到需要的数据  
    18.         //2 版本更新  
    19.         handleUpdate(VersionInfo(url: "应用下载地址", title: "有新版本啦!", message: "提示更新内容,解决了xxx等一系列问题,新增了xxx等功能!", must_update: false, version: "3.5"))  
    20.     }  
    21.       
    22.     /// 版本更新  
    23.    private static func handleUpdate(_ info: VersionInfo) {  
    24.         guard let localVersion = localVersion()else { return }  
    25.         if isIgnoreCurrentVersionUpdate(info.version) { return }  
    26.         if versionCompare(localVersion: localVersion, serverVersion: info.version) {  
    27.             let alert = UIAlertController(title: info.title, message: info.message, preferredStyle: .alert)  
    28.             let update = UIAlertAction(title: "立即更新", style: .default, handler: { action in  
    29.                 UIApplication.shared.open(URL(string: info.url)!)  
    30.             })  
    31.             alert.addAction(update)  
    32.             if !info.must_update { //是否强制更新  
    33.                 let cancel = UIAlertAction(title: "忽略此版本", style: .cancel, handler: { action in  
    34.                     UserDefaults.standard.set(info.version, forKey: "IgnoreCurrentVersionUpdate")  
    35.                 })  
    36.                 alert.addAction(cancel)  
    37.             }  
    38.             if let vc = UIApplication.shared.keyWindow?.rootViewController {  
    39.                 vc.present(alert, animated: true, completion: nil)  
    40.             }  
    41.         }  
    42.     }  
    43.       
    44.    // 版本比较  
    45.    private static func versionCompare(localVersion: String, serverVersion: String) -> Bool {  
    46.         let result = localVersion.compare(serverVersion, options: .numeric, range: nil, locale: nil)  
    47.         if result == .orderedDescending || result == .orderedSame{  
    48.             return false  
    49.         }  
    50.             return true  
    51.     }  
    52.       
    53.     // 是否忽略当前版本更新  
    54.     private static func isIgnoreCurrentVersionUpdate(_ version: String) -> Bool {  
    55.         return UserDefaults.standard.string(forKey: "IgnoreCurrentVersionUpdate") == version  
    56.     }  
    57. }  

    简单说明:
    1 代码的实现很简单,上面只是简单写了一个测试数据,真正的数据需要自己在每次程序启动之后向服务端请求数据。
    2 提供了获取本地版本、版本更新、版本比较、是否忽略当前版本更新等4个方法。isIgnoreCurrentVersionUpdate方法是表示当用户选择忽略版本之后下次启动程序,对于当前版本不再进行更新提示


    Swift有对应的版本更新库(Siren),有需要的可以参考和使用。


    展开全文
  • 苹果官方的文档一般都很少去看,笔者参考官方文档和各路大神的经验,写下了一份基于Swift 4.0 的编码规范,并会持续更新,欢迎大家补充指正。 编码格式 命名规范 语法规范 1. 编码格式 1.1 使用二元...

    自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]
    
    展开全文
  • 该文章翻译自Apple官方文档: The Swift 4 Programming Language ...Guards翻译组 正在翻译Swift 4的全套文档, 这是该文档第二章节《Basic Operators》的上半部分, 第一章节《The Basics》 上半部分请点这里...

    原文链接:http://blog.csdn.net/feng2qing/article/details/73864580

    该文章翻译自Apple官方文档: The Swift 4 Programming Language

    Guards翻译组 正在翻译Swift 4的全套文档, 这是该文档第二章节《Basic Operators》的上半部分, 第一章节《The Basics》 上半部分请点这里/下半部分请点这里, 原文链接: Basic Operators

    翻译 : Stevin三天三夜 (Blog / GitHub)

    校对 : Jonhory (简书 / GitHub)

    译者心声

    我们会不定期的更新翻译文章, Guards翻译组本周内会发布 Basic Operators下半部分 章节中文版. 如感兴趣,可以关注<我们的简书,获取翻译组更多文章>

    我们是一群热爱翻译并且热爱 swift 的人, 希望通过自己的努力让不熟悉英语的程序员也能学习到国外的高质量的文章. 如发现文章中翻译错误之处, 烦请跟我们联系, 我们第一时间更正.

    想成为我们中一员? 是的, 我们正在招募对翻译感兴趣的小伙伴, 如果你想提高阅读英语文档的水平, 如果你不甘寂寞, 如果你想为广大开发者做点事. QQ:835087646

    本篇包含内容:

    • 基本运算符
    • 术语
    • 赋值运算符
    • 算数运算符
    • 求余运算符
    • 一元减号运算符
    • 一元加号操作符
    • 复合赋值运算符
    • 比较运算符
    • 三元条件运算

    基本运算符

    运算符是检查,改变或合并值的特殊符号和短语。比如:加号(+)是将两个数相加,如 
    let i = 1 + 2,和逻辑AND元运算符(&&)结合两两个布尔值,比如:if enteredDoorCode && passedRetinaScan

    Swift支持多数标准 C 操作符,并且为了消除常见的编码错误改进了几种特性。例如:赋值运算符(=)没有返回值。防止当使用判等运算符(==)的地方错误地使用它。算术运算符(+-*%等)检测不允许值溢出,来避免保存变量的时候变量取值范围大于或小于其取值范围导致的异常结果。你也可以使用Swift的溢出运算符实现溢出,详见Overflow Operators

    Swift还提供了 C 没有的区间运算符,比如:a..<ba...b,快捷地表达了区间内的数值。

    本章描述了Swift常见的运算符,Advanced Operators这章涵盖了Swift的高级运算符,并且介绍如何自定义运算符和标准实现运算符自定义类型。

    术语

    运算符有一元运算符、二元运算符和三元运算符。

    • 一元运算符针对单个对象操作,比如-a,一元运算符分为前置运算符和后置运算符,前置运算符的运算符在对象前面,如!b,后置运算符的运算符在对象后面,如c!.
    • 二元运算符操作两个对象,如2 + 3,是放在中间的,出现在两个运算对象之间。
    • 三元运算符操作三个对象,像C语言一样,Swift只有一个三元运算符,条件运算符a ? b : c.

    运算符影响的值叫操作数,在表达式1 + 2中,+是二元运算符,它的两个操作数是12

    赋值运算符

    赋值运算符(a = b)用b的值初始化或更新了a的值:

    let b = 10
    var a = 5
    a = b
    // 此时 a 等于10

    如果赋值的右边是一个多元组,那它的元素被分成多个常量或变量:

    let (x, y) = (1, 2)
    // 此时 x 等于 1,y 等于 2

    Swift的赋值操作符不同于 C 和 Objective-C, 它没有返回值,所以下面的代码是错误的:

    if x = y {
        // 这是错误的,因为x = y没有返回值
    }

    这个特性能够防止你使用(==)的时候而错误的写成(=),因为if x = y是无效的,Swift能够帮助你避免这种类型错误的发生。

    算数运算符

    Swift支持所有数值类型的常见四则运算

    • 加法(+
    • 减法(-
    • 乘法(*
    • 除法(/
    1 + 2           // 等于3
    5 - 3           // 等于2
    2 * 3           // 等于6
    10.0 / 2.5      //等于4.0

    Swift的算数运算符不同于 C 和 objective-c 的是默认情况下不允许溢出。你可以使用Swift的溢出运算符进行溢出运算(如:a &+ b),详见Overflow Operators.

    加法运算符也支持String的拼接

    "hello, " + "world"     // 等于 “hello, world”
    

    求余运算符

    求余运算符(a % b)计算出b的多少倍恰好合适a并且返回剩余的值(称作余数)

    NOTE:
    在其他语言中求余运算符也叫做取模运算符,然而严格的来说在Swift中它对负数的操作行为,它是一个余数而非取模。

    求余计算的方式,计算9 % 4,你先计算出多少个4恰好适合9

    两个4恰好适合9,余数是1(橙色部分显示)

    在Swift中表达为:

    9 % 4       // 等于1

    为了得到a % b的答案,%运算符计算了以下等式并且返回余数作为结果:

    a = (b * 倍数) + 余数

    当倍数取到最大值的时候乘上b就恰好适合a

    94放入等式中

    9 = (4 * 2) + 1

    相同的方法,可以计算负数

    -9 % 4      // 等于-1

    -94放入等式可以得到

    -9 = (4 * -2) + -1

    余数是-1 
    对于负数b求余的时候,b的符号会被忽略,意味着a % ba % -b结果是一样的。

    一元减号运算符

    数值的符号可以切换使用前缀-,称为一元减号运算符

    let three = 3
    let minusThree = -three         //minusThree等于-3
    let plusThree = -minusThree //plusThree等于3,或“负负3”

    一元减号(-)直接在操作数之前,中间没有任何空格

    一元加号操作符

    一元加号操作符(+)只是简单地返回了操作数的值,没有做任何改变

    let minusSix = -6
    let alsoMinusSix = +minusSix        //alsoMinusSix等于-6

    尽管一元加号操作符实际上没有做任何事情,但当你使用一元减号操作符的时候可以使用它来为提供代码提供对称性。

    复合赋值运算符

    想C一样,Swift也提供把赋值运算符(=)和其他运算符结合起来的复合赋值运算符,比如说其中的*加法赋值运 
    算符*(+=

    var a = 1
    a += 2
    a 现在等于 3

    表达式a += 2是 a = a + 2的简写,有限地将加法和赋值合成一个运算符同时执行两项任务

    NOTE 
    复合赋值运算符没有返回值,比如说你不能这样写:let b = a += 2

    对了,Swift提供的标准库提供的复合赋值操作符完整列表,详见Swift Standard Library Operators Reference。

    比较运算符

    Swift支持所有标准 C 语言中的比较运算符

    • 等于(a == b
    • 不等于(a != b
    • 大于(a > b
    • 小于(a < b
    • 大于等于(a >= b
    • 小于等于(a <= b

    NOTE 
    Swift也提供了恒等(===)和不恒等(!==)两个比较符用于测试两个对象是否引用同一个对象的实例,更多信息详见Classes and Structures.

    每个比较运算符都返回了一个布尔值来标识语句是否为真

    1 == 1      //为真,因为1等于1
    2 != 1      //为真,因为2不等于1
    2 > 1       //为真,因为2大于1
    1 < 2       //为真,因为1小于2
    1 >= 1      //为真,因为1大于或小于1
    2 <= 1      //为假,2并不小于或等于1

    比较运算符经常用于条件语句,比如if语句

    let name = "world"
    if name == "world" {
        print("hello, world")
    } else {
        print("I'm sorry \(name), but I don't recognize you")
    }
    // 输出“hello world”,因为name确实等于“world”

    更多短语if语句,详见Control Flow 
    只要元组中的每个值都相同,你也可以比较相同数量值的元祖。比如:IntString都可以比较,这意味着类型(Int,String)类型的元组可以比较,相反,布尔值不能比较,这意味着包含布尔值的元祖不能比较。 
    元组的比较从左到右,每次比较一个值,直到比较发现两个值不相等,比较完这两个值,比较的结果决定了元组比较的总体结果,如果每个元素都相等,那么元组本身也相等,比如:

    (1, "zebra") < (2, "apple")   //为真,因为1小于2;“zebra”和“apple”不比较
    (3, "apple") < (3, "bird")    //为真,因为3等于3;“apple”小于“bird”
    (4, "dog") == (4, "dog")      //为真, 因为4等于4;"dog"等于"dog"

    在上面的示例中,第一行左右比较的行为,因为1小于2,就决定(1, "zebra")小于(2, "apple"),而不去考虑元组中的其它值,”zebra“不小于”apple“并不重要,因为元祖的第一个元素已经决定了比较结果,然而,当元组的第一个元素相同的时候,就像第二行和第三行一样,比较他们的第二个元素。

    NOTE 
    Swift标准库包含了少于7个元素的元组比较运算符,七个或更多元素的元祖比较时,你必须自己实现比较运算。

    三元条件运算

    三元条件运算符的特殊性在于它有三部分操作数,像:问题 ? 答案1 : 答案2,这个基于问题真或假决定两个表达式中选出一个的简洁操作。如果问题为真,则返回值为答案1,否则,返回值为答案2
    三元条件操作符简短地描述了下面的代码

    if question {
        answer1
    } else {
        answer2
    }

    这有一个计算表行高的例子,如果有表头,行高应该高于内容50像素,如果没有表头,高于内容20像素。

    let contentHeight = 40
    let hasHeader = true
    let rowHeight = contentHeight + (hasHeader ? 50 : 20)
    // 行高等于90

    前面的例子要比下面的代码简洁

    let contentHeight = 40
    let hasHeader = true
    let rowHeight: Int
    if hasHeader {
        rowHeight = contentHeight + 50
    } else {
        rowHeight = contentHeight + 20
    }
    // 行高等于90

    第一个例子使用了三元条件运算符一行代码就能算出rowHeight,这比第二个例子的代码更简洁。 
    三元条件运算符为需要考虑的两个表达式提供了高效的简写,然而,使用三元条件运算符也需要谨慎。过度使用会导致简洁的代码变的很难读懂。避开的一个组合语句中使用多个三元条件运算符的情况。

     

    展开全文
  • 您可以使用Xcode 11.4构建以Swift 5.2,Swift 4.2或Swift 4编写的目标。 当您使用Xcode 11.4生成Swift 4Swift 4.2代码时,大多数Swift 5.2功能都可用。也就是说,以下更改仅适用于使用Swift 5.2或更高版本的代码...
  • Swift5.0新特性更新

    2019-02-12 09:48:13
    原文博客地址: Swift 5.0新特性更新 期待已久的Swift 5.0终于来啦, Swift 5.0是Swift中最备受关注的一个版本, 传说中API稳定的版本 随着Xcode Bate 10.2的发布, Swift 5.0也发布了测试版, 相信也带来了很多优化和...
  • Swift 4是苹果计划于2017年秋季推出的最新版本,其主要重点是提供与Swift 3代码的源兼容性,并努力实现ABI稳定性。 本文重点介绍对Swift的更改将对您的代码产生最大的影响。 而且,让我们开始吧!
  • Swift编程语言(Swift 5)

    2020-07-10 23:30:52
    https://www.cnswift.org/ 内容pdf版, 已更新Swift 5. 介绍: 《Swift 编程语言》是苹果官方对 Swift ...所以我独立发起了这个手册的翻译工作——与其他现存翻译不同的是:它同步更新苹果官方的 Swift 开发者预览版 !
  • Swift 5已经发布下面是官方swift5的介绍。 IntroducingSwift 5.1 Swift 5.1now makes it easier to create and share binary frameworks with others. It also includes features that make it easier to design ...
  • Swift 4.0 新特性

    2017-08-15 19:37:46
    WWDC 2017 带来了很多惊喜,在这次大会上,Swift 4 也伴随着 Xcode 9 测试版来到了我们的面前,虽然正式版要8月底9月初才会公布,但很多强大的新特性正吸引我们去学习它。根据大会上已经开放的新特性,先一睹为快。...
  • iOS 弹出更新提示、评价app提示(swift版) 提示更新,评价app 。
  • 最近做个项目,需要实时的监听网络连接状态,网络连接断开时需要提醒用户手动打开网络,网络重新连接上之后需要做些操作。
  • Swift项目,为适配iOS10,无奈只能更新Xcode 8 ,可是发现一入3.0深似海,从此幸福是路人.于是边摸索边修改,在节前的完成代码迁移.节后在完成手头工作后,整理思路,把swift3迁移的心得分享大家. 废话不多说分享下心得: ...
  • Swift-App版本更新

    2017-04-20 17:41:35
    iOS开发中,有时会有这种需求,在AppStore上出现新版本时,应用内弹窗提示用户更新.自动提示更新的实现方案分为两种: 第一种,自己服务器提供一个接口,通过请求,获取app的相关的版本信息,如:是否需要更新,以及...
  • swift入门教程面向单位实际需求,资深讲师,提供实用swift课程,swift案例教学,从swift基础到项目实战,解决工作中实际问题,ios开发入门必选课程,全面学习Swift编程语言的技术体系,通过大量案例掌握Swift在项目开发中的...
  • swift 线程更新UI

    2019-06-13 01:57:45
    为什么80%的码农都做不了架构师?>>> ...
  • Swift Package Manager 使用教程2020更新 Package Manager Swift Package Manager是管理 Swift 代码分发的工具。它已经和Swift的build system进行了整合,能够自动下载、编译和链接依赖。 Package Manager目前支持...
  • Swift 4 现已正式发布!Swift 4 在 Swift 3 的基础上,提供了更强大的稳健性和稳定性,为 Swift 3 提供源码兼容性,对标准库进行改进,并添加了归档和序列化等功能。 你可以通过观看 WWDC 2017: What’s New in...
1 2 3 4 5 ... 20
收藏数 18,710
精华内容 7,484
热门标签