分類(lèi)
- 新建一個(gè)空的Swift文件(一般命名比如String+Exrension),直接用extension來(lái)寫(xiě)即可辣辫。
- 可以在一個(gè)文件里寫(xiě)多個(gè)分類(lèi)
extension String
{
// MARK: - 沙盒路徑
func cachesDir() -> String {
let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!
let lastName = (self as NSString).lastPathComponent
let filePath = (path as NSString).stringByAppendingPathComponent(lastName)
return filePath
}
func documentDir() -> String {
let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!
let lastName = (self as NSString).lastPathComponent
let filePath = (path as NSString).stringByAppendingPathComponent(lastName)
return filePath
}
func tmpDir() -> String {
let path = NSTemporaryDirectory()
let lastName = (self as NSString).lastPathComponent
let filePath = (path as NSString).stringByAppendingPathComponent(lastName)
return filePath
}
}
命名空間
- 注意:如果想通過(guò)一個(gè)字符串創(chuàng)建一個(gè)類(lèi)犹赖,那么必須加上命名空間,否則創(chuàng)建出來(lái)的是nil
let aClass : AnyClass = NSClassFromString("XMGWeibo." + "HomeViewController")!
- 直接把命名空間寫(xiě)死比較low徒役,比較好的做法是動(dòng)態(tài)獲取。直接去info.plist獲取即可
// 從info.plist動(dòng)態(tài)獲取命名空間
// 這里通過(guò)key去字典取值窖壕,取到的是anyObject類(lèi)型的忧勿,是可選類(lèi)型杉女。要對(duì)其操作必須解包。這里用guard來(lái)解包
guard let name = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] else
{
KSLog("name為空")
return
}
// 拼接命名空間.類(lèi)名
// NSClassFromString返回的類(lèi)型是AnyClass?
let aClass: AnyClass? = NSClassFromString("\(name)."+controllerName)
- 注意:如果出現(xiàn)aClass為nil的情況鸳吸,先去設(shè)置一下APP的名字熏挎,build settings -> Product Name和Product Module Name
Swift中的類(lèi)
- AnyObject:相當(dāng)于OC中的id,表示所有class類(lèi)型的數(shù)據(jù)晌砾;所有繼承于NSObject的類(lèi)都隱式地實(shí)現(xiàn)了protocol Anyobjct協(xié)議坎拐,所以他可以表示所有class類(lèi)型
- 小知識(shí)點(diǎn):Swift中的數(shù)組Array和String類(lèi)并不繼承于A(yíng)nyObject,而是一個(gè)結(jié)構(gòu)體养匈,所以不能用Anyobject表示
- 字典/數(shù)組只能存儲(chǔ)對(duì)象哼勇,所以通過(guò)一個(gè)key從字典中獲取值取出來(lái)的是一個(gè)AnyObject類(lèi)型。并且有可能取不到呕乎,所以最終類(lèi)型是AnyObject?
- Any:所有的基本數(shù)據(jù)類(lèi)型积担,包括enum/struct都可以用Any來(lái)表示
- 小知識(shí)點(diǎn):Swift中可以寫(xiě)let array:[AnyObject] = ["abc",1],而不報(bào)錯(cuò)猬仁,看似和上面的說(shuō)法矛盾帝璧,其實(shí)array里的屬性已經(jīng)被默認(rèn)轉(zhuǎn)換成OC里的數(shù)據(jù)類(lèi)型了
- AnyClass:用來(lái)表示元類(lèi)型(任意類(lèi)的類(lèi)型),它的內(nèi)部實(shí)現(xiàn)是:typealias AnyClass = AnyObject.Type湿刽。
- .Type的意思是用于獲取類(lèi)的元類(lèi)型聋溜。類(lèi)如Person.Type就代表獲取Person的元類(lèi)型
- .self:如果通過(guò)類(lèi)名調(diào)用,那么可以獲取該類(lèi)的類(lèi)型叭爱,說(shuō)白了就是獲取自己
- 類(lèi)似于OC中
[UITableViewCell Class]
- 于是可以這么寫(xiě):let typeP : Person.Type = Person.self,意思是用Person類(lèi)型的變量typeP把Person這個(gè)類(lèi)保存起來(lái)撮躁;然后可以用typeP調(diào)用Person的類(lèi)方法。比如typeP.say(),效果和Person.say()是一樣的买雾。為什么要多此一舉呢把曼?主要是用于解耦:外界傳入一個(gè)類(lèi),可以用這個(gè)方法把這個(gè)類(lèi)保存起來(lái)然后調(diào)用類(lèi)方法漓穿,如果直接Person調(diào)用嗤军,那么就寫(xiě)死了
回到上面的命名空間問(wèn)題
- 上面創(chuàng)建了一個(gè)AnyClass類(lèi)型的aClass變量,但如果打印它晃危,會(huì)發(fā)現(xiàn)什么都沒(méi)有叙赚,因?yàn)橄到y(tǒng)還不知道它的具體類(lèi)型的,所以必須將他轉(zhuǎn)換為已知的類(lèi)型僚饭,再調(diào)用init()方法創(chuàng)建
- 直白的說(shuō)震叮,Swift中如果想通過(guò)一個(gè)Class來(lái)創(chuàng)建一個(gè)對(duì)象,必須告訴系統(tǒng)這個(gè)Class的確切類(lèi)型
// 根據(jù)完整類(lèi)名創(chuàng)建控制器鳍鸵,這里aClass要強(qiáng)轉(zhuǎn)成UIViewController類(lèi)型的才能用init方法
// aClass是可選類(lèi)型苇瓣,這里用guard來(lái)解包
guard let classType = aClass as? UIViewController.Type else{
return
}
let childViewController = classType.init()
異常
- Swift中的異常機(jī)制不一樣。OC中一般發(fā)生錯(cuò)誤會(huì)給傳入的指針賦值偿乖,而Swift中使用的是異常處理機(jī)制
- 凡是有throws的方法击罪,那么必須進(jìn)行try catch處理
- 只有do里面的代碼發(fā)生了錯(cuò)誤哲嘲,才會(huì)執(zhí)行catch里的代碼
- try :正常處理異常,也就是通過(guò)do catch來(lái)處理
- try! :告訴系統(tǒng)一定不會(huì)有異常媳禁,也就是說(shuō)可以不通過(guò)do catch來(lái)處理眠副。但開(kāi)發(fā)中不推薦這么寫(xiě)
- try? :告訴系統(tǒng)可能有錯(cuò),也可能沒(méi)錯(cuò)竣稽。如果沒(méi)錯(cuò)囱怕,系統(tǒng)會(huì)自動(dòng)將結(jié)果包裝成一個(gè)可選類(lèi)型返回,如果有錯(cuò)丧枪,系統(tǒng)會(huì)返回nil光涂。如果使用了try?庞萍,也可以不通過(guò)do catch來(lái)處理
// filePath是根據(jù)一個(gè)key來(lái)取值的拧烦,可能不存在,是可選類(lèi)型钝计,需要解包
guard let filePath = NSBundle.mainBundle().pathForResource("MainVCSetting.json", ofType: nil) else
{
KSLog("JSON文件不存在")
return
}
// data也是可選類(lèi)型恋博。如果不用guard處理,用alt點(diǎn)擊可以看到有個(gè)問(wèn)號(hào)私恬。(用guard處理了就看不到了)
guard let data = NSData(contentsOfFile: filePath) else
{
KSLog("加載二進(jìn)制數(shù)據(jù)失敗")
return
}
do
{ // json轉(zhuǎn)對(duì)象债沮,順便強(qiáng)轉(zhuǎn)為字典數(shù)組類(lèi)型
let obj = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! [[String: AnyObject]]
for dict in obj {
// 上面的字典里value是AnyObject類(lèi)型,需要強(qiáng)轉(zhuǎn)為String
let title = dict["title"] as? String
let VcName = dict["vcName"] as? String
let imageName = dict["imageName"] as? String
addChildViewController(VcName, title: title, imageName: imageName)
}
}catch
{
KSLog("接受服務(wù)器控制器數(shù)據(jù)失敗,顯示默認(rèn)控制器")
addChildViewController("HomeController", title: "首頁(yè)", imageName: "tabbar_home")
addChildViewController("MessageController", title: "消息", imageName: "tabbar_message_center")
addChildViewController("DiscoverController", title: "發(fā)現(xiàn)", imageName: "tabbar_discover")
addChildViewController("ProfileController", title: "我", imageName: "tabbar_profile")
}
// 這里的obj是個(gè)可選類(lèi)型本鸣,如果出錯(cuò)疫衩,那么是nil
let obj1 = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)
// 這里如果出錯(cuò),那么直接崩
let obj2 = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)
斷言
- 與異常有類(lèi)似的作用荣德,用于告訴使用者闷煤,某個(gè)值不能為空。如果為空涮瞻,直接崩潰并且打印錯(cuò)誤信息
assert(access_token != nil, "使用loadUserInfo()方法前必須先授權(quán)")
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者