$0 $1 swift

2017-09-05 13:13:42 feosun 阅读数 1453

Swift 自动对行内闭包提供简写实际参数名,你也可以通过 0,1 , $2 等名字来引用闭包的实际参数值。

如果你在闭包表达式中使用这些简写实际参数名,那么你可以在闭包的实际参数列表中忽略对其的定义,并且简写实际参数名的数字和类型将会从期望的函数类型中推断出来。 in 关键字也能被省略,因为闭包表达式完全由它的函数体组成:

let numbers = [3,2,4,1,5,7,6];

var sortedNumbers = numbers.sorted(by:{$0 < $1});
print(sortedNumbers);//输出为:[1, 2, 3, 4, 5, 6, 7]

sortedNumbers = numbers.sorted(by:{$1 < $0});
print(sortedNumbers);//输出为:[7, 6, 5, 4, 3, 2, 1]

可以看出,可以用01、20指代第一个参数,12指代第三个参数,以此类推n+1n后的数字代表参数的位置,一一对应。

2018-04-24 20:24:52 daiqiao_ios 阅读数 1871

swift 自动为闭包提供了参数缩写功能,可以直接通过 01等来表示闭包中的第一个第二个参数,并且对应
的参数类型会根据函数类型来进行推断。如下代码:

不使用 $0、$1来代替闭包参数

let sortedArray = [2,3,5,6,7]
let tempSum = sortedArray.sorted { (a, b) -> Bool in
return a > b
}
print(sortedArray) //[7, 6, 5, 3, 2]

使用$0 ,$1

let sortArray = sortedArray.sorted(by: {$0 < $1})
print(sortArray) //[2, 3, 5, 6, 7]

通过上面的代码可以发现使用$0、$1的话,参数类型可以自动判断,并且 in关键词可以省略,也就是
只用写函数体就可以了。

2016-08-16 14:10:26 Felicity294250051 阅读数 1233

关于Swift 3.0的具体使用指南大家可以去阅读Swift 3.0中文文档(Swift 3.0 中文文档)和Swift 3.0官网文档(Swift 3.0 官网文档

1.首当其冲的就是闭包的修改。

升级完Xcode8之后根据提示会默认帮你进行一些修改。但是修改完成还有500+多个错误很大一部分是闭包的修改,我的内心是这样的。

在Swift2.3中我们写闭包是这样写:

    //Swift 2.2
    typealias detailCollectBlock = (state:Bool)->Void

    var detailCollect:detailCollectBlock?

    func detailCollect(detailCollect:detailCollectBlock)
    {
        self.detailCollect = detailCollect
    }

    //在需要的时候调用
    self.detailCollect?(state:true)

    //
    controller.detailPraise({ (state) in
        model.isPraise = (state ? "1" : "0")
            })
    //Swift3中的 使用方法1 
    typealias detailCollectBlock = (Bool)->Void

    var detailCollect:detailCollectBlock?

    func detailCollect(detailCollect:@escaping detailCollectBlock)
    {
        self.detailCollect = detailCollect
    }
    //在需要的时候调用
    self.detailCollect?(true)

    //在上页面回调接收的时候的用法
    controller.detailPraise(detailPraise: { (<#Bool#>) in
         model.isPraise = (state ? "1" : "0")
            })

    //使用方法2
    typealias detailCollectBlock = (_ state:Bool)->Void

    var detailCollect:detailCollectBlock?

    func detailCollect(_ detailCollect:@escaping detailCollectBlock)
    {
        self.detailCollect = detailCollect
    }

    //在需要的时候调用
    self.detailCollect?(state:true)

    //
    controller.detailPraise({ (state) in
        model.isPraise = (state ? "1" : "0")
            })

这个时候大家应该就可以从代码中发现,swift3中需要定义闭包的时候不需要命名参数名,只需要告诉参数类型即可.

现在迁移我们也可以使用方法2,这时我们的参数在使用时还是省略的(就和2.2时使用相同),外部调用闭包的时候就不需要在修改了。这样可以减少很多工作量,因为项目中的闭包实在是太多了..

如果闭包不是在当前作用域内执行而是还要继续传递到别的函数里的话, 那就必须加上@escaping,本身的意思是逃逸的

别接收回调的地方也和swift2.2不同,回调方法中会有block的名字,但是没有参数名了(方法2中就没有名字啦),只有参数的类型,我们需要自己来定义参数的名称.

详情见SE-0103SE-0118

2.在Swift2.3中我们函数在被调用时的第一个参数名会被省略,除非在前面在此定义eq:

//这样才会在调用的时候显示参数名 swift2.2时
func addCollect(detailId detailId)

在Swift3中我们不需要在这样做了。会一直带有第一个参数名

3.UIControlState等的表示状态的常量 都变成了首字母小写

//Swift2.2
self.toolsView?.praiseButton.setImage(UIImage.init(named: "tool_icon_like_normal"), forState: .Normal)

self.phone?.componentsSeparatedByString() //swift2.2

//swift3
self.toolsView?.praiseButton.setImage(UIImage.init(named: "tool_icon_like_normal"), for: .normal)

self.phone?.components(separatedBy: "-") //swift3

这样做也是为了脱离OC冗长的方法命名,精简了语意,但是可读性还需要长时间的检验吧

3.使用NSDictionary的修改

dict.setObject(true, forKey: "state")
dict.setObject(num, forKey: "key")

在之前我们一直使用NSDictionary(<font color=gray>因为从OC转过来感觉还是NSarray和NSDictionary用起来顺手的</font> ),用来设置key的时候。现在需要添加NSCopying ,所以我都改成Dictionary啦哈哈。现在我们也应该在之后写代码的时候避免使用NSString,NSArray, NSDictionary等因为现在更加不方便了~~

4.泛型

//swift2.2
 var selectResult:PHFetchResult?

//swift3
 var selectResult:PHFetchResult<PHAsset>?

这个是项目中图片管理器所用到的,现在就是需要在PHFetchResult后面告诉它是什么类型,也可以是AnyObject
这个后面还需要详细的介绍。给自己挖个坑

5.没有了CGRectMake 改用CGRect.init来初始化或者我们写一个他的扩展.来模拟之前的CGRectmake

//用来代替,修改的CGRectMake
func CGRectMake(_ x:CGFloat,_ y:CGFloat,_ width:CGFloat,_ height:CGFloat)->CGRect
{
    return CGRect.init(x: x, y: y, width: width, height: height)
}

6.关于颜色的初始化方法UIColor.color都去掉了括号,并且color的后缀页去掉了,新添加了Url类,也是为了脱离OC的NSUrl吧.

7.GCD的改变 更加Swift化.

DispatchQueue.main.async {
    let controller = LoginViewController()
    self.present(controller, animated: true, completion: nil)
                }

其实GCD的用法没有太多的改变,只是写法变的更加Swift,去掉了之前C语言的形式,多写读多熟悉应该就好了。

9.NSString操作的变化

//swift2.2
   let ch = (pinYinString as NSString).character(at: 0)
//swift3
    let ch=pinYinString?.unicodeScalars[(pinYinString?.unicodeScalars.startIndex)!]

因为我需要取到拼音的首字母来进行排序,所以需要获取到首字母的ASCII码。所以使用NSString更方便。但是现在不能这样用了,所以我们只能使用Swift中的这个unicodeScalars来获取啦。

8.枚举变成了小写,自己定义的时候是大写当他变成.语法的时候Xcode页把它变成了小写

2014-12-29 14:47:44 cg1991130 阅读数 6010

        本人是个IOS开发新手,之前没有接触过Objective-C语言,直接从最新的Swift学起,进行IOS8的学习开发。由于Swift语言是一门全新的语言,网上的资料很少,遇到问题百度搜到的都是英文的页面。通过一段时间的学习,我基本掌握了Swift的语法,坚持使用Swift进行IOS8的开发对我们提升自己的Swift编程能力很有帮助。相信很多人学习Swift语言都选择了《Swift开发指南》这本书,我觉得这本书写的不错,但是在自己动手演练本书21章的计算器项目时,遇到了一些问题,书中并没有给予纠正,网上下载的示例代码中也没有改正。下面说说我在手敲这个项目时的心得体会,希望能给其他Swift爱好者带来帮助。

        我使用的是APP store中下载的最新版的Xcode6.1.1.一般的项目都是由底层向顶层开发,按照书中的步骤,业务逻辑层中的类CalcLogic中应用了之前定义的一个枚举类型,但是实例名使用了Operator(书中是大写的,网上代码里小写,都会报错,因为operator是系统关键字,所以我把实例名换成了operator1),代码如下:

<pre name="code" class="cpp">class CalcLogic{
    //保存上一次的值
    var lastRetainValue:Double
    //最近一次选择的操作符
    var operator1:Operator
    //临时保存MainLabel内容,为true时,输入数字MainLabel内容被清0
    var isMainLabelTextTemporary:Bool
...
}



       之后在定义方法calculateByTag 时我遇到了一个让我哭笑不得的错误,calculateByTag中有一个switch开关语句,其中在case .Divide中有一个if else判断语句,我按照之前的编程习惯,把else单独放在一行,后来一直报错,直到我查阅了书籍,发现书中的else和前后大括号的写法都是“
 } else { ”,改成这样的形式后错误消失了,在赋值语句中同样会遇到报错,一个=前后都应该有空格,所以奉劝大家在做Swift开发的时候一定要养成敲空格的好习惯T T。代码段如下

func calculateByTag(tag:Int,withMainLabelString mainLabelString:String)->String{
    var currentValue = (mainLabelString as NSString).doubleValue
        switch operator1{
        case .Plus:
            lastRetainValue += currentValue
        case .Minus:
            lastRetainValue -= currentValue
        case .Multiply:
            lastRetainValue *= currentValue
        case .Divide:
            if currentValue != 0 {
                lastRetainValue /= currentValue
            } else {
            operator1 = .Default
                isMainLabelTextTemporary = true
                return "错误"
            }
        default: lastRetainValue = currentValue
        }

      另外一点要注意,switch中的默认关键字是小写的“default”,书中写成了大写的,这是错误的,不要跟case中的.Default搞混,这个大写开头的Default是我们之前在Operator枚举类型中自己定义的。书中代码引用的变量都没有加强制拆封,也就是“!”,但是在实际编程中Xcode会提示你加上“!”。

       同样是这个方法中,Operator的静态方法fromRaw在Xcode中提示已经被取代了!Xcode帮我改成了如下格式:

operator1 = Operator(rawValue: tag)!

      表示层开发中没有遇到很大的难点,有以下几点需要注意的:首先,在给tag赋值的时候我没找到“tag”,后来发现是属性监测器工具栏太长了屏幕没有显示完全,往下拖一点就找到了(原谅我是个新手),其次,书中的Xcode应该不是最新版本,因为在Xcode6.1.1中的“辅助编辑器”图标已经变了,大家注意一下,现在的图标是两个圆圈的样子,如图所示:




       最后完成图如下:




遗憾的是,我完成的计算器的小数点按键在点击时会报错,目前还没找到原因,不知道大家的作品是怎么样的呢?



2018-04-02 09:56:09 fish_yan_ 阅读数 8417

Swift 中的变量声明相对于 OC 中简化了很多。可变与不可变取决于声明的方式,不在取决于类型了,这样简化了很多不必要的类型。比如 OC 中可变的为 NSMutableArray,不可变的是 NSArray,而 Swift 中的数组不管可变与不可变就是 Array 。

Swift 中变量的声明

在 Swift 中声明变量有两种方式: let,var

Swift 中的变量的声明方式跟 OC 大不相同,摒弃了 OC 中的 alloc init 的方式,在写法上进行了简化,使整体的入门难度降低,但仅仅是入门难度降低了。

let

let 所声明的变量统统为不可变的变量。

    let a: Int = 0

这是简单的声明了一个 Int 类型的变量 a ,a 的值只能是初始值 0 ,不能被再次修改,一般结构:let (变量名):(类型) = (值)

    a = 1

如果在写上面这句代码,编译器就会直接给出报错提示Cannot assign to value: 'a' is a 'let' constant, 所以在用let声明的变量,是不能被再次赋值,包括修改。这一点跟 OC 中的不可变类型有区别,OC 中是不能被修改,但是可以被重新赋值。

Swift 中声明一个变量是不是看起来很简单?对,入门很简单,But… 举几个例子:

    let a = 0 // Int 类型的 0
    let a: Int = 0 // Int 类型的 0
    let a = 0.0 // Double 类型的 0
    let a: Float = 0 // Float 类型的 0
    let a: Double = 0 // Double 类型的 0
    let a = {
        return 0
    }()

为什么 let a = 0Int 类型而 let a = 0.0 就是 Double 类型的呢?在 Swift 中有类型推断的机制,当你声明一个变量,如果没有指定类型,那么系统就会去推断这个变量是什么类型的。

var

var 所声明的变量统统为可变的变量。

    var a: Int = 0
    a = 3

如果上面没有写 a = 3 那么系统会给出黄色提示 Variable 'a' was never mutated; consider changing to 'let' constant 提示你声明的是一个可变的变量而你没有修改它,建议用 let 修饰。

Swift 是类型安全的语言,所以在对类型的要求比较严格。如果你不需要修改变量那么就用 let 声明,如果你需要修改那么就用 var 声明。

同样举几个例子,跟 let 一样就不解释了

    var a = 0 // Int 类型的 0
    var a: Int = 0 // Int 类型的 0
    var a = 0.0 // Double 类型的 0
    var a: Float = 0 // Float 类型的 0
    var a: Double = 0 // Double 类型的 0
    var a = {
        return 0
    }()

本篇只是简单介绍一下一个变量的声明方式,区分一下 letvar 的区别,什么时候用 let,什么时候用 var,对于那些希望从 OC 转向 Swift 语言开发的希望有些帮助。想要了解更多的 Swift 的知识请往下看。