AnyObject 、Any、 AnyClass;as、 as?、 as! ;try try?、 try! 的区别
? 和 !
? 表示可选的 !表示一定有值的否则解析时会报错
一,AnyObject, Any
-
AnyObjet 代表任何Class类型实例对象,相当于OC中的id
public typealias AnyObject
// The protocol to which all class types implicitly conform. 只适用于class类型
typealias Complicate = (AnyObject) ->Void
//请求回调
var complicate : Complicate?
func request(type:RequestType, URLString:String, parameters:[String : AnyObject], complicate:@escaping Complicate) -> Void {
CK().maskShow()
switch type {
case .requestTypeGet:
Alamofire.request(URLString, method: .get, parameters: parameters, encoding: JSONEncoding.default, headers: nil)
.validate()
.responseJSON { response in
CK().dismissMask()
switch response.result{
case .success:
if let value = response.result.value{
//把得到的JSON数据转为字典
complicate(value as AnyObject)
}
case .failure: ()
DMCAlertCenter.default().postAlert(withMessage: “网络请求失败”)
return
}
}class Man{ } class Woman{ } let man = Man() let woman = Woman() var arr:[AnyObject] = [man,woman] for people in arr { if let m = people as? Man { println("这是个男人") }else if let w = people as? Woman { println("这是个女人") } }
-
Any 是一个空协议集合的别名,它表示没有实现任何协议,因此它可以是任何类型,包括类实例与结构体实例 比AnyObject范围更广,代表除函数外的任何类型的实例
不仅适用于class还适用于struct,enum,func等
实例1:
参数parameters的key是String类型,但是value值可以是任何类型
parameters = [“appId”:“123456”, “timestamp”:203428394820,
“version”:“1.0”, “bizContent”:[“pageStart”:1, “pageSize”: “10”,“isTrue”:true]] as [String : Any]
实例2:
class Man{
}
class Woman{
}
var arr:[Any] = Any
arr.apppend(1)
arr.append(“hangge.com”)
arr.append(Man())
arr.append(Woman())
for any in arr {
switch any {
case let any as Int:
println(“这是个Int类型”)
case let any as String:
println(“这是个String类型”)
case let any as Man:
println(“这是个男人类型”)
case let any as Woman:
println(“这是个女人类型”)
default:
println(“这是个未知类型”)
}
} -
AnyClass 使用不多,更多体现在系统内的使用。是AnyObject.Type的别名而已
属于AnyObject.Type的别名:typealias AnyClass = AnyObject .Type
表示任意类的元类型,任意类的类型都隐式遵守这个协议,一般我们使用不多
AnyObject是Any的子集
所有用class关键字定义的对象就是AnyObject
所有不是用class关键字定义的对象就不是AnyObject,而是Any
AnyObject是一定不能为空,包括初始化的时候
AnyObject!表示类型是一个optional类型,初始化的时候可以为空,但是加!表示知道用它时它是一定不为空的。
二,as, as?, as!
- as 用来做类型转换
从派生类转换为基类,向上转类型(upcasting)
class Animal{}
class Dog:Animal{}
let cat = Dog()
let dog = cat as Animal
消除二义性,数值类型转换
let num1 = 4 as Int
let num2 = 5.09 as CGFloat
switch语句中进行模式匹配
如果不知道一个对象是什么类型,可以通过switch语法检测他的类型,并且尝试在不同类型下使用对应的类型进行相应的处理。
switch animal{
case let dog as Dog:
print(“如果是Dog类型对象,则做相应处理”)
case let cat as Cat:
print(“如果是Cat类型对象,则做相应处理”)
default: break
}
- as?
不确定的关系
let man = Man()
let woman = Woman()
var arr = [man,woman]
for people in arr {
if let m = people as? Man {
println(“这是个男人”)
}else if let w = people as? Woman {
println(“这是个女人”)
}
}
is 用来做类型检查
for people in arr {
if let m = people is Man {
println(“这是个男人”)
}else if let w = people is Woman {
println(“这是个女人”)
}
}
as?和as!操作符的转换规则是一样的,只是as?在转换失败之后会返回nil对象,转换成功之后返回一个可选类型(optional),需要我们拆包使用。
由于as?转换失败也不会报错,所以对于能够100%确定使用as!能够转换成功的,使用as!,否则使用as?
let animal:Animal = Cat()
if let cat = animal as? Cat{
print(“这里有猫”)
}else{
print(“这里没有猫”)
}
- as!
向下转型(Downcasting)时使用,由于是强制类型转换,如果转换失败会报runtime运行错误
let animal:Animal = Cat()
let cat = animal as! Cat
as :类型一致或者子类
仅当一个值的类型在运行时(runtime)和as模式右边的指定类型一致 - 或者是该类型的子类 - 的情况下,才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成as模式左边指定的模式。
as! 父类强转子类
as? 转换失败返回nil
三,try, try?, try!
- try
异常处理try catch的使用
swift异常处理 历史由来
Swift1.0版本 Cocoa Touch 的 NSError ,Swift并没有真正的具备自己的异常处理机制
Swift2.0版本 加入 ErrorType protocol
Swift3.0版本 改名 Error protocol
Swift3.0 Error protocol 的使用
首先定义一个枚举,集成协议Error (Swift 2.0 的协议叫做ErrorType,3.0后协议改名Error)
enum MyError : Error {
case one
case two
case three
}
throws和throw的使用
使用throws放在参数列表后面标明一个方法有异常抛出,标准格式 : func 方法名字 (参数列表) throws -> 返回值类型 并在方法内使用throw抛出异常
func testFunc(str: String) throws -> String {
if str == “one” {
throw MyError.one
}else if str == “two” {
throw MyError.two
}else if str == “three” {
throw MyError.three
}
return “ok”
}
使用do-catch处理异常
do {
var str = try testFunc(str: “three”)
} catch MyError.one {
print(“MyError.one”)
} catch MyError.two {
print(“MyError.two”)
} catch let error as MyError {
print(error)
}
// 1.获取JSON文件路径
let path = NSBundle.mainBundle().pathForResource("MainVCSettings.json", ofType: nil)!
// 2.加载JSON文件
let data = NSData(contentsOfFile: path)!
// 3.将JSON文件加载进来的数据转换为对象 字典数组
//try结合do..catch一起使用
do {
// 编写有可能出现错误的代码
let objc = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)
}catch {
// 只要do后面大括号中的代码抛出了异常, 就会执行catch
// 如果do后面大括号中没有抛出异常, 那么catch后面大括号中的代码不执行
WFLog(error)
}
-
try?
Swift2.0 后加入了新的关键字 try? , 如果不想处理异常那么可以用这个关键字,使用这个关键字返回一个可选值类型,如果有异常出现,返回nil.如果没有异常,则返回可选值 相当于告诉系统可能有错, 也可能没错, 如果发生错误, 那么返回nil, 如果没有发生错误, 会见数据包装成一个可选类型的值返回给我们
这种使用方式, 相当于忽略错误 .例子如下
enum MyError : Error {
case one
case two
case three
}func testFunc(str: String) throws -> String { if str == "one" { throw MyError.one }else if str == "two" { throw MyError.two }else if str == "three" { throw MyError.three } return "ok" } var str = try? testFunc(str: "three") print(str)
控制台输出
nil
Program ended with exit code: 0
-
try!
告诉系统一定没错, 如果发生错误, 程序会崩溃. 不推荐使用.例子如下
enum MyError : Error {
case one
case two
case three
}func testFunc(str: String) throws -> String { if str == "one" { throw MyError.one }else if str == "two" { throw MyError.two }else if str == "three" { throw MyError.three } return "ok" }
var str = try! testFunc(str: “three”)
控制台:程序奔溃掉~
try 出现异常处理异常
try? 不处理异常,返回一个可选值类型,出现异常返回nil
try! 不让异常继续传播,一旦出现异常程序停止,类似NSAssert()