swift3.0学习
可选值
可选值:有可能被设置为nil,所有类型都可以被设置.?表示不能拿来运算.!强制解包,如果没有值会崩溃.swift中不会给变量或常量赋初值.
空合运算符:??使用可选值的时候使用.如果有值使用可选值,无值使用后面一个
可选绑定:在条件判断语句中,定义一个临时的变量或常量x,将可选值y的值,赋值给x.如果y有值,则赋值成功,可以使用x,如果y没有值,绑定不成功,可以做异常处理,简称iflet,另一个guardlet,可以减少代码的层级.
iflet
//可以避免频繁的使用?和!
var a1:Int? =5
var b1:Int? =10
if let x = a1{
let c = x + 10
}else{
print("a1没有值")
}
if let a1 = a1, let b1 = b1,b1>5,a1>2{
let c1 = a1 + b1
}
guardlet
func testguard(){
guard let a1 = a1,let b1 = b1,b1>5,a1>2 else{
return
}
let c1 =a1+b1+5
}
可选值举例说明
let string = "http://www.baidu.com/哈哈"
let url = URL(string:string)
在开始时是nil,所以是可选值
var window: UIWiondow?
复杂的数据类型
- 字符串
//let 定义一个不可变的字符串,var定义一个可变的字符串
let str:String = "hello,world"
var str1:String = "hello"
str1.append(",love you")
str.append(",love you") //报错
//拼接
var str2 = str +str1
str2 += ",love you"
//与变量常量拼接,最常用
let name = "xiaoming"
var str3 = "hello,\(name)"
let h = 5, m= 5,s = 5
let time = String(format:"%02d:%02d:%02d",h,m,s)
//字符串的比较,最常用
var stra = "hello"
var strb = "hello"
if stra == strb{}
//字符串是否有前后缀
let result = stra.hasPrefix("h") //前缀
let result1 = stra.hsaSuffix("loa")//后缀
//字符串长度(个数)
let count = strc.characters.count
//字符串的长度(字节数)
let countbytes= strc.lengthOfBytes(using:String.Encoding.utf8)
//range
let strd = "hello,girl"
let index2 = 1
let index3 = 3
let rang = 1...3
let startIndex = strd.startIndex
let endIndex = strd.endIndex
let secondIndex = strd.index(startIndex,offsetBy:1)
let fourIndex = strd.index(startIndex,offsetBy:3)
let swiftRange = secondIndex..<fourIndex
let subStr = strd.substring(with:swiftRange)
//range简单用法
let stre = (strd as NSString).substring(with:NSMakeRange(1,3))//as 类型转换
- 数组
//可变不可变
let arr = ["dog","cat","pid"]
var arr1 = ["dog","cat","pid"]
var arr2:[String] = Array()
var arr3:[String] = []
//数组的遍历
for item in arr1{
print(item)
}
for item in arr1.enumerated(){
pring("\(item.element),\(item.offset)")
}
for item in arr1.enumerated().reversed(){
pring("\(item.element),\(item.offset)")
}
//生成新的倒序数组
let reversedArray = Array(arr1.reversed())
//数组的拼接
let array1 = ["dog","cat"]
let array2 = ["pig","goat"]
var array3 = array1 + array2
//增
array3.append("cow")
//删
array3.remove(at:2)
//改
array3[1] = "snake"
- 字典
//字典的定义
let dic = ["first":"dog","second":"cat"]
var dic1 = ["first":"dog","second":"cat"]
dic1["second"]=nil
let first = dic1["first"]//返回可选值
let dic3:[String:String] = Dictionary()
let dic3:[String:String] = [:]
//Any 和AnyObject
//任何类型和对象
//字典的遍历
let dic5 = ["first":"dog","second":"cat"]
for (k,v) in dic5{
print("\(k),\(v)")
}
let keys = Array(dic5.keys)
let values Array(dic5.values)
//字典的操作//字典的操作都是围绕key值做操作
//增
dic6["third"]= "pig"
//删除
dic6["first"]= nil
//改
dic6["second"]= "snake"
//查,返回的是可选值
let second = dic6["second"]
函数和闭包
- 函数
func 函数名 (参数1:类型,参数2:类型) -> 返回值类型{}
函数参数的默认值,一旦设了默认值,该参数可传可不传.
func addNum(a:Int=5,b:Int)->Int{
return a + b
}
addNum(b:20)
func methodOne () ->Void{
print(#function)
}
//Void是一个空的元组
methodOne()
//有参数没有返回值
func add(a:Int,b:Int){
print("\(a)和\(b)相加,值是\(a+b)")
}
add(a:5,b:10)
//有参数,有返回值
func caculate(a:Int,b:Int)->Int{
return a + b
}
let result = caculate(a:5,b:10)
//函数的参数
//first叫外部参数名,对参数a做解释说明用的
//swift默认给函数的每一个参数都加了一个和形参名字一样的外部参数名,也可以自己定义外部参数名.
func caculatea(first a:Int,second b:Int)->Int{
return a + b
}
let result = caculatea(first:5,second:10)
//我们也可以选择忽略外部参数名
func caculateb(_ a:Int,_ b:Int)->Int{
return a + b
}
let result = caculateb(5,10)
//外部参数名,如果不忽略就必须传
- 闭包:是一个匿名的函数块.函数就是闭包,闭包就是函数,本质就是函数指针.闭包被完整的包括在{}里.
闭包的定义和调用
//定义一个无参无返回值的闭包
func methodOne(){
print("hello")
}
methodOne()
let closureOne = {
print("hello")
}
closureOne()
//定义一个有参数,无返回值的闭包
func methodTwo(a:Int,b:Int){
print("a+b =\(a + b )")
}
methodTwo(a:5,b:10)
let closureTwo = {
(a:Int,b:Int) in
print("a+b =\(a + b )")
}//不会默认给参数添加解释名
closureTwo(5,10)
//定义一个有参数,有返回值的闭包
func methodThree (a:Int,b:Int)->Int{
return a + b
}
let result = methodThree(a:5,b:10)
let clousureThree={
(a:Int,b:Int)->Int in
return a + b
}
let result = clousureThree(5,10)
异步加载的时候使用
//下载一部movie,完成后更新ui
尾随闭包
当闭包可以写在函数的最后一个参数,可以写在函数外面.
如果函数只有该闭包表达式一个参数,则连小括号都可以省略
deinit{
print("byebye")
}
-
window的设置
- 循环引用
downloadMovie{
[weak self](movie:String) in
self!.label.text = movie
}
- 闭包修饰符
总结
swift3.0
类与对象
class Person:NSObject{}
protocol personDelegate:NSObjectProtocol{}
struct MyRect{}
enum MyCase{}
class Dog:NSObject{
var name = "旺财"
init(name:String){
self.name = name
}
//便利构造器,必须调用指定构造器完成构造过程
convenience init(namea:String){
self.init(name:namea)
}
}
class Person:NSObject{
//存储属性,节省cpu,消耗cpu
var name:String
var age:Int
//可选属性,代表这个属性可能有值,可能是nil
var girlFriend:String?
//计算属性,一定有return值的,节省内存,消耗cpu
var kindName:String{
return "亲爱的\(name)"
}
//懒加载属性
lazy var pet :Dog = Dog()
lazy var pet: Dog = {
()->Dog in
let dog = Dog()
dog.name = "小白"
return dog
}()
//构造函数,创建一个对象(完成类的构造的方法)
//构造函数,可以有多个,都叫init
init(name:String,age:Int){
self.name = name
self.age = age
//自动调用super.init()
}
}
let xiaoming = Person(name:"xiaoming",age:20)
print("name:\(xiaoming.name),age,\(xiaoming.age)")
//就是调用一个方法
let kindname = person.kindName
let pet = person.pet
类的属性
存储属性:一直保留
计算属性:调用后立即创建和释放,相当于一个函数
可选属性:属性可以被设置为nil
懒加载属性:调用时初始化初始化
只需要考虑存储属性
1.创建一个类,如果没有自己实现构造函数,会有一个默认的构造函数,就是init(){super.init()},指定构造器
2.一旦定义了自己的构造器,则默认就失效
3.便利构造器,简化类的构造过程
let button = UIButton(type:.contactAdd)
- kvc构造器
kvc是基于运行时的,运行时是oc的特性.在swift中,使用kvc时,如果基本的数据类型设为可选,是不兼容的.可以给基本的数据类型,设一个初值
import Foundation
//kvc构造函数:
class Person:NSObject{
var name:String?
var age:Int? = 0
init(dict:[String:Any]){
super.init() //调用完成后,对象已经被创建
setValuesForKeys(dict)
}
override func setValue(,forUndefinedkey ){}
}
重载:参数不同.