概述阶段
iOS崩溃的常见原因
1.系统库向上兼容问题,某些方法明确被废弃,在新版本系统中无法运行
2.系统库向下兼容问题,某些库只能在高版本系统中使用,老系统并不支持
3.本地数据储存结构变化,但未兼容过去的数据(用户已安装老版本APP),初始化时无法正确读取数据
4.访问的数据类型不是期望的数据类型而产生崩溃,常见的问题:NULL、Number类型。解决方案:最优势服务器端加入默认值,其次可以在客户端接收数据后立即进行整体处理,全转为String
5.数组越界
6.野指针
7.内存处理不当,内存泄露。常见于:照片模块、地图模块、block回调
- NSTimer未销毁,timer只要加入了runloop,那么它就会对于self进行持有,直到[timer invalidate],所以如果使用timer,一定要记得释放
Swift知识点:
1.swift中的Array和[]是一个东西,编译器会自动识别
2.Swift中可以使用OC对象,OC对象所能使用的方法依然是OC中的方法
3.OC对象是否可变是根据自身类型来的,比如:let声明的NSMutableArray对象,依然可以增删改
4.OC中的可变对象往往不能直接转成Swift对象,比如:NSMutableArray无法直接转为Array
5.Dictionary字典类型依然是由index这个相关属性的,但是字典本身是无序的,所以这个index的用法并不是很明朗
代码阶段
Array、NSArray、 NSMutableArray的创建和转换
/**** 方式1、2、3、4均是Swift数据类型 方式5、6是OC数据类型 ****/
//数组建立方式1:默认建立
let list1 = ["你好","2","3","4"]
//数组建立方式2:指定类型String
var list2:[String] = ["你好","2","3","4"]
//数组建立方式3:指定类型Any
let list3:[Any] = ["你好","2","3",3,UILabel()]
//数组建立方式4:指明Array类型
let list4:Array<Any> = ["你好","2","3","4",UILabel()]
//数组建立方式5:指明NSArray类型
let list5:NSArray = ["你好","2","3","4",UILabel()]
//数组建立方式6:指明NSMutableArray类型
let list6:NSMutableArray = ["1","2","3","4"]
/**** 想把 NSArray 转为 Array ****/
//NSArray转换写法1:依靠自动推到,这样写系统推断出的类型为Array<AnyObject>
let list7:Array = list5 as Array
print(list7)
//NSArray转换写法2:指定数组内容的类型,转换后即为Array<Any>
let list8 = list5 as! Array<Any>
print(list8)
//NSMutableArray转换写法1:这样写虽然可以,但编译器会报警告
let list9 = list6 as! [Any]
print(list9)
//NSMutableArray转换写法2:遍历存储
var list10:Array<String> = Array()
for item in list6 {
list10.append(item as! String)
}
print(list10)
//Array中添加删除修改,只有其用var修饰符才可以操作
var list11 = list8
//Swift对象只能用append
list11.append("11")
list11.removeAll()
//而OC对象不受修饰符影响,NAArray不可增删改,NSMutableArray依然用OC中的方法增删改
let list12 = list6
//OC对象只能用add
list12.add("12")
list12.removeAllObjects()
Array的增删改以及遍历
var list1 = ["1", "2", "3", "4", "5"]
//在某一位置添加,原位置元素向后移
list1.insert("0", at: 0)
//在末尾添加
list1.append("6")
//["0", "1", "2", "3", "4", "5", "6"]
print(list1)
//修改某个位置的元素
list1[0] = "zero"
//修改某一段,替换进去的Array长度并无要求,
list1[0..<3] = ["zero", "one"]
//["zero", "one", "3", "4", "5", "6"]
print(list1)
//删除某一位置元素
list1.remove(at: 0)
//
print(list1)
//常规遍历
for item in list1[0..<3] {
print(item)
}
//元组遍历
for (index, value) in list1.enumerated() {
print("Item \(index): \(value)")
}
Array的map()函数和flatMap()函数
//Swift中,数组的每一个元素都需要执行一项操作,除了用for循环,还可以用map函数
//map()是 Array 提供的方法,通过接收一个函数作为传入参数,对数组中每个元素进行函数变换得到新的结果值。
//这样只需要提供X->Y的映射关系,就能将数组[X]变换到新数组[Y],而无需创建一个临时可变数组
let lsits = ["张三", "张三的爸爸", "李四", "李四的爸爸"]
let closure = {(str:String) -> String in
var result = str
if str.contains("张三") {
result = "尊敬的" + str
}
return result
}
//["尊敬的张三", "尊敬的张三的爸爸", "李四", "李四的爸爸"]
print(lsits.map(closure))
//如果内部操作足够简单,还有这种写法
print(lsits.map {$0 + ",你好" })
//map函数中可以嵌套map函数
let numbers2 = [[1,2,3],[4,5,6]];
let result2 = numbers2.map{ $0.map{ $0 + 2 } }
// [[3, 4, 5], [6, 7, 8]]
print(result2)
//除了map还有flatMap()方法,
//如果map()是X->Y,那么flatMap()就是X->Y?,且flatMap()会剔除nil的数据
//简单的说:flatMap()除了给每个数据绑定一个固定的操作外,还可以剔除不符合要求的数据
let numbers3 = [1,2,3,4];
let result3 = numbers3.flatMap { (v) -> String? in
if v <= 2 {
return nil
}
return String(v)
}
//["3", "4"],注意这里还会的是一个[String]数组了
print(result3)
Array的Sort()函数
let numbers = [12,25,1,35,27]
//常规写法
let numbersSorted = numbers.sorted{ (n1, n2) -> Bool in
//index越大,值越小,倒序
return n2 < n1
}
print(numbersSorted)
//极简写法(index越大,值越大,正序)
let numbersSorted2 = numbers.sorted {$1 > $0}
print(numbersSorted2)
//终极蛇皮写法(正序)
numbers.sorted(by: <)
Dictionary的创建和删除
//Swift中只要满足Hashable协议,都可以做字典的key
var intDict = [Int: String]()
//float或double类型也可以
var doubleDict = [1.1:"1",2.1:"2"]
//甚至Data、Date类型均是可以的
var dateDict = [Date(): "当前时间"]
//此时,不指定类型,默认dict的推断类型为[String:String?]
var testDict:[String:String?] = ["key1": "value1", "key2": nil]
//在初始化时,value中可以存在nil值,但是后续添加元素的时候不允许再添加nil值
testDict["key3"] = nil
//["key2": nil, "key1": Optional("value1")]
print(testDict)
//updateValue()更新值方法,同时它会有一个返回值,返回该key旧的值
//如果该key在原字典中不存在,那么返回值就会为nil
if let oldValue = testDict.updateValue("value4", forKey: "key4") {
print("The old value for DUB was \(oldValue).")
}
print(testDict)
//只要这个key在原字典中存在,返回值就有效
if let oldValue = testDict.updateValue("value2", forKey: "key2") {
//会被打印
print("The old value for is \(oldValue).")
}
//["key2": Optional("value2"), "key4": Optional("value4"), "key1": Optional("value1")]
print(testDict)
//删除方式1
testDict.removeAll()
//true
print(testDict.isEmpty)
//删除方式2
testDict = [:]
//true
print(testDict.isEmpty)
Dictionary的遍历
var dict = [1:"23",3:"3",5:"23",7:"3"]
//元组遍历方式
for (key, value) in dict {
print("\(key): \(value)")
}
for key in dict.keys {
print("打印key值: \(key)")
}
for value in dict.values {
print("打印Value值: \(value)")
}
//dict.keys不是常见的Array数组,需要进行转换才可成为正常的Array
//更准确的说dict.keys是LazyMapCollection类型,这是种可以强转为Array的类型
let keys = [Int](dict.keys);
print(keys);
Dictionary的index
/*
虽然dict是无序的,但实际上dict依然可以使用dict.index()和dict.enumerated()
甚至还可以根据index去remove,这一点很奇怪
这里的index依然可以作为索引找到对应元素,但实际上是无序的
没事不要去用了,会出问题的
*/
//唯一正常的和index相关的用法
//先找到key对应的index值
let index = dict.index(forKey: 1)
//然后删除它
dict.remove(at: index!)
//打印
for num in dict.enumerated() {
print("打印信息:index:",num.offset,"value:",num.element)
}