虽然Swift这门语言还很年轻,但是不可否认的是Swift很强大,也很便捷,但是习惯于OC编程之后再去写swift难免会觉得别扭,今天有时间,我就来把Swift的一些知识点加以整理,也便于自己以后查阅和重新温习,争取每天一篇,第一天就从最基础的开始整理
首先是新建一个swift工程,这个和OC是一样的,只不过在建的过程中把OC语言改成swift,这里就不再赘述
1.swift的基本操作
1.字符串操作
在swift中 let表示常量 var 表示变量
let str = "hello"
//长度str.characters.count
//长度 str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
//大小写转换
//str.uppercaseString
//str.lowercaseString
//相等 == 拼接 +
//插入 "123\(str)4567"
//格式化创建字符串 加占位符的
let str3 = String(format: "%02d:%02d", arguments: [1,2])
let str2 = String(format: "%02d:%02d", 1,2)
print(str2)
print(str3)
//字符串的其他操作全部转换为NSString再去操作
//转换 的方法
let str4:NSString = str2 as NSString
2.数组的操作
Swift的数组和OC的数组可以互相转化
//不可变数组
let array1 = ["A","3","C"]
//可变数组
var mutableArray = [String]()
//往数组中添加元素
mutableArray.append("world")
在这里要说一下的是这个 let array= [String]()
这个式子表示的是 初始化一个存放字符串类型的空白数组
()代表初始化 OC里的initWith/init 在swift里面全部转化成()
在对数组操作有个要注意的点
1.for -in遍历数组的时候一定要明确的指出数组的类型
for temp in array1 as [String]{
print(temp.characters.count)
}
2.元组遍历数组中的值
for (index, value) in array1.enumerate()
{
print("index = \(index),value = \(value)")
}
3.字典的操作
在OC中字典要用 {} 表示 但是在swift中我们依然用[ ] 表示字典,这是一个不想同的点
1.不可变字典
let dict = ["key1":"value1","key2":"value2","key3":"value3"]
//通过key值访问value值
print(dict["key1"])
1.1 for-in 元组遍历字典的时候和数组有不同的地方,不用在后面加枚举,直接遍历即可
//for -in 遍历 (不用在后面加枚举)
for (key,value) in dict
{
//print("key = \(key), value = \(value)")
}
2.可变字典
var dict2 = ["key":"value"]
2.1如果可变字典合并另一个字典
这里要注意的时 如果key存在于原字典则是一个更新键值对的操作,否则是增加键值对操作
//合并
for (key,value) in dict
{
dict2[key] = value
}
4. 可选类型 封包 解包
//如果一个值可能为nil,那么这个值就是可选类型,用?标识
//Optional包围的就是可选类型
//可选类型不能直接使用,必须进行强制解包,!强制解包,对nil进行强制解包就会崩溃
如果swift出现了这个错误 fatal error: unexpectedly found nil while unwrapping an Optional value
那么原因就是对一个空的可选类型进行强制解包
下面举个例子
var a1:String?
a1 = "皮卡皮卡"
print(a1!.characters.count)
补充:有人经常会看到这样的语句 (a1 ?? "123") 这个语句是什么意思呢
这个语句的意思就是对可选类型进行判断,如果为空就给一个值"123",这是对可选类型进行一个保护让它解包时不至于崩溃
print((a1 ?? "123").characters.count)
5. 判断
1.if判断
swift的if判断和OC有两点的不同
1.1 if 条件语句()可省略,{}不能省略
1.2 判断没有非零即真的概念,只有true false的两种情况这样可以使判断更准确效率更高更有针对性
let tempValue = 10
if tempValue > 5
{
print("这很Swift")
}
2.三种可选类型的条件分支
2.1 if-let
if-let 是对可选类型的判断,如果可选类型为空,则不执行代码块,如果不为空时,用tempStr来接收此刻这个可选类型的解包后的值 只能判断可选类型
let string:String? = "比比鸟"
if let tempStr = string
{
print(tempStr)
}
2.2 if-let-where
跟 if-let 相似,where是对前面定义的这个局部变量再做一层判断
如果不为空且位数大于2
let string:String? = "比比鸟"
if let tempStr1 = string where tempStr1.characters.count > 2
{
print("tempStr1.length = \(tempStr1.characters.count)")
}
2.3 guard-let-else(守护)
跟 if-let 相反 如果可选类型str为nil,则执行代码块,最后一定要return,如果不为nil则强制解包后的值赋值给tempStr,这样在{}外面就可以使用tempStr
let str:String? = nil
guard let tempStr = str else
{
print("str = nil")
return
}
print(tempStr)
3.switch
在这里我们也着重注意下swift中的switch和OC中的switch的区别
3.1 在swift中
(1).switch不局限判断整型,可以是浮点型,也可以是字符串等等
(2).switch 后面的小括号可以省略,大括号不能省略
(3).case后面至少要有一条执行语句,并且case后面的大括号可以省略,break可以不写,不会造成贯穿
(4).default一定要写,且只能写在最后
写法为
let f = 3.2
switch f
{
case 3.0:
print("凑数的判断语句")
case 3.1:
print("这还是一个凑数的")
case 3.2:
print("这又是一个凑数的")
default:
print("这是default的判断语句")
}
6.循环
因为OC的while和do while和swift相差并不大所以就不再赘述 我简单总结下for循环
下面的写法虽然最熟悉但是这个写法在2.2版本已经废弃了
for (var i = 0;i < 5;i++){
}
现在我的swift的写法是这样的 但是好像最新版本的swift好像也会报错,这个我等会看一下
for var i = 0 ; i < 10 ; i++
{
print(i)
}
2种for in循环
注意区分两者的不同 差别在" ." 和 "< "
这是0-4的遍历
for i in 0..<5
{
print("i = \(i)")
}
这是0-5的遍历
for i in 0...5
{
print("i = \(i)")
}
7.枚举
老规矩,先对比OC来看
相对于OC来说swift的枚举更加强大 swift的枚举值可以关联浮点型,字符串,并且没有默认的关联值
注意观察下面两个代码的差别
关联如果是int,会默认的递增上去,如果不是int类型的话,必须每个枚举值都关联上
enum Month:Init
{
case January = 3
case February
case March
case April
}
enum Month:Float
{
case January = 11.2
case February = 12.2
case March = 13.2
case April = 14.2
}
调用枚举
如果明确指出一个变量/常量是属于哪种枚举类型的话,可以直接.枚举值赋值,否则就 枚举类型.枚举值
let month = Month.April
let month1:Month = .January
switch month
{
//hasValue 代表第几个枚举
case .January:
print("hasValue = \(month.hashValue),rawValue = \(month.rawValue) ")
print(month)
case .February:
print("hasValue = \(month.hashValue),rawValue = \(month.rawValue) ")
print(month)
case .March:
print("hasValue = \(month.hashValue),rawValue = \(month.rawValue) ")
print(month)
case .April:
print("hasValue = \(month.hashValue),rawValue = \(month.rawValue) ")
print(month)
}
2.常用swift的操作
1.懒加载
swift的懒加载格式为
lazy var 变量名:变量类型 = {
code 初始化
return
}()
以 初始化一个button为例
lazy var btn:UIButton = {
var tempBtn = UIButton(type:UIButtonType.ContactAdd)
tempBtn.frame = CGRectMake(90,100,50,50)
tempBtn.backgroundColor = UIColor.cyanColor()
return tempBtn
}()
2.闭包
闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。
在Swift中的闭包与C、OC中的blocks和其它编程语言(如Python)中的lambdas类似。
闭包格式 闭包作用回调传值
var 闭包变量 ={
(参数名:参数类型)-> 返回值类型 in
代码块
}
具体实现
//无参无返
let closure = {
()->()//() -> void , ()
in
print("无参无返")
}
closure()
//有参无返
let closure1 = {
(tempStr1 str:String,tempStr2 str2:String) -> ()
in
print("有参无返")
}
closure1(tempStr1: "hello",tempStr2: "world")
//无参有返
let closure2 = {
() -> String
in
print("无参有返")
return "aaaaa"
}
print(closure2())
//有参有返
let closure3 =
{
(str:String) -> Int
in
return 32
}
print(closure3("给我打印个数吧"))
3.方法 的声明和实现
格式
func 方法名(参数列表) ->返回值类型{
}
具体的实现代码
func text(str:String) ->String
{
return "有参有返"
}
func text1()->String
{
return "无参有返"
}
func text2()
{
print("无参无返")
}
func text3(str:String)
{
print("有参无返")
}
print(text("啦啦啦"))
print(text1())
text2()
text3("哈哈哈哈")
把闭包作为参数的方法实现示例
假如我们要实现两个string的拼接
首先声明一个方法在方法内部执行闭包
func combineString(str1:String,str2:String,closure:(tempStr1:String,tempStr2:String)->String)
{
//执行闭包
let string = closure(tempStr1: str1, tempStr2: str2)
print(string)
}
调用的时候实现函数
combineString("hello", str2: "world") { (tempStr1, tempStr2) -> String in
return "\(tempStr1) \(tempStr2)"
}
4.单例的创建
首先创建一个继承与NSObject的类 因为swift没有 .h文件所以直接就在文件中创建单例
创建单例有两种写法
写法1
var name:String?
static var shareSingleDog:singleDog = {
let instance = singleDog()
return instance
写法2
static let instance = singleDog()
static func shareSingleDog()->singleDog{
return instance
}
写法1的调用
let s1 = singleDog.shareSingleDog
s1.name = "皮卡"
let s2 = singleDog.shareSingleDog
print(s2.name)
写法2的调用
let s3 = singleDog.shareSingleDog()
s3.name = "水箭龟"
let s4 = singleDog.shareSingleDog()
print(s4.name)
5.KVC异常捕获
在OC中我们经常使用KVC在swift中也有需要注意的点
1.字典转模型
(1)新建模型类 以person为例
var name:String?
var age:Int = 0
var gender:String?
这里需要注意模型中如果有基本数据类型的话,基本数据类型不可以为可选类型,否则在KVC赋值中会找不到对应的key值.如果为可选类型的话必须给个初始值
(2)重写初始化方法
init(dict:[String:AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
重写完初始化方法后,系统自带的默认初始化方法就不能被调用,如果还想调用默认的初始化方法则需要写下以下的方法
override init() {
}
(3)外界字典转模型
let dict = ["name":"zhangsan","age":12,"gender":"男"]
let person = Persone(dict: dict)
//let person = Persone() (系统自带的初始化方法)
print(person.name)
print(person.age)
print(person.gender)
2.解析
1.获取路径
let path = NSBundle.mainBundle().pathForResource("iOS04", ofType: "json")
如果返回值是可选类型的就需要解包
如果实在记不住解包,可以写完根据提示来补全
let data:NSData = NSData (contentsOfFile: path!)!
do{
let rootArray = try NSJSONSerialization .JSONObjectWithData(data, options: .MutableContainers) as! [[String:String]]
print(rootArray)
}catch
{
//异常捕获序列化出错的时候就会自动来到这里
print("error")
}
最后需要注意的一点就是
swift里面尽量不要写self一般只有在闭包内部才会强制要求写self
以上就是swift基础部分的简单总结