命名空间
swift中引入了命名空间的概念,只要在同一个命名空间下所有的资源都是共享的,而且默认情况下项目名称就是命名空间;如果使用swift开发中使用第三方框架最好使用cocospad
,这样第三方的所有东西都会被另外一个工程所管理,不会因为命名空间问题产生,变量等的重定义。
1、获取命名空间名称
//获取命名空间
let namespace = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String`
//用字符串创建类
let aClass = NSClassFromString(namespace + "." + valueTypeString)
//用字符串创建控制器
let namespace = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String
// let cls = NSClassFromString(namespace + "." + "HomeTableViewController") as! UIViewController.Type
let clsName = NSClassFromString(namespace + "." + "HomeTableViewController")
let cls = clsName as! UIViewController.Type
let vc = cls.init()
print(vc)
2、修改命名空间名称
可选类型
1、swift中的方法或者数据类型后面有一个?
就代表返回的是一个可选类型Optional。
2、可选值必须解包才可以参加计算,如果不解包可选值会被Optional包裹,是不能参加计算的
3、应该尽量使用guard let ... else
和if let
解包,避免一堆?
和!
的情况
4、只有在迫不得已而且绝对确定强制解包不会导致崩溃的情况下,才使用强制解包,否则可能导致程序崩溃
1、可选类型的定义?
var name:String?//可选类型定义
name = "Hello world!!!"
print(name) //打印输出结果Optional("Hello world!!!")
print(name!)//强制解包输出结果Hello world!!!
2、可选类型解包
2.1、强制解包!
:强制解包就是在需要强制解包的变量后面添加一个!
var fullName:String?
print(url!)//强制解包,奔溃
fullName = "姓名"
print(url!)//强制解包成功
为避免因为强制解包导致的奔溃,swift提供了可选值绑定
2.2、可选解包使用guard let ... else
和if let
解包
if let & guard let 的命名技巧:直接使用同名
//guard let ... else
var fullName:String?
var firstName:String?
var secondName:String?
fullName = "姓名"
firstName = "名字"
secondName = "姓氏"
guard let full_name = fullName,
first_name = firstName,
second_name = secondName else
{
return;//本次解包不成功可选值存在`nil`,退出本次解包,也可能使用到`continue`
}
//解包成功
print(full_name + "," + first_name + "," + second_name)
//if let
var fullName:String?
var firstName:String?
var secondName:String?
fullName = "姓名"
firstName = "名字"
secondName = "姓氏"
if let full_name = fullName,
first_name = firstName,
second_name = secondName
{
//解包成功
print(full_name + "," + first_name + "," + second_name)
}
2.3、guard case let / if case let
2.4、for case let
2.5、switch case let
类型转换
swift不存在隐式类型转换
1)基础类型转换
目的类型(变量)
刚好不同与OC
2)可选类型,对象,结构体类型转换is
,as
,as?
,as!
因为swift中的结构体和class都可以通过()
来创建,所有基础类型的转换方法是不能做类型转换的
3)swift中除去String
类型,其他多数情况下as
需要使用as?
和as!
,起码我很少见到
//is
是否可以做类型转换,可以返回true,不可以返回false
//as
//as?
带条件的类型转换,返回optional类型,转换成功返回转换后的值,失败返回nil
//as!
强制转换,返回指定类型,转换失败运行时报错
//as?和as!选择
要进行转换的是as?使用as?,是as!使用
懒加载
1、swift中的懒加载与OC不同,懒加载的闭包只会执行一次,然后分配独立的存储空间
,即使将懒加载的变量直接设置为nil闭包也不会再执行一次,所以不要在内存警告的时候将懒加载的view设置为nil,从父控件移除
2、懒加载的本质是闭包
3、懒加载只在结构体和class中有效,不要在playground
中直接使用
4、通常情况下只要在有初始化的变量前添加关键字lazy
即可懒加载变量var name = ""
懒加载称为lazy var name = ""
5、只能懒加载变量,常量不能懒加载
6、懒加载的构造方法没有智能提示,eg:UITableView
懒加载就没有智能提示构造方法,得生敲
//完整版的懒加载代码
lazy var myView:UIView = { ()->UIView in
return UIView()
}()
//常用的懒加载代码
lazy var myView:UIView = {
//逻辑判断
return UIView()
}()
lazy var myView:UIView = UIView()
lazy var name = ""
@objc
1、swift中使用@objc
修饰的类型可以通过OC的Runtime的消息机制进行调用
2、在把按钮定义槽方法private
后需要用@objc
修饰槽方法,否则会调用失败,如果不用@objc
修饰会报错
3、在使用optional
关键字定义协议方法的时候需要用@objc
修饰协议,因为swift中的协议方法默认是必须实现的,选择实现是OC的特性
//按钮槽方法
button.addTarget(self, action: #selector(test), for: .touchUpInside)
@objc private func test()
{
}
//定义协议
@objc protocol MyProtocol {
optional func test() -> Int
}
.self,.Type,.Protocol
1、.self
可以用在类型后面取得类型本身,也可以用在某个实例后面取得这个实例本身
2、.Type
可以用在类型后面表示的是某个类型的元类型
3、.Protocol
可以用在protocol类型后面表示的是某个protocol类型的元类型
//注册cell
self.tableView.registerClass(
UITableViewCell.self, forCellReuseIdentifier: "myCell")
//类型转换
vcType as! UIViewController.Type
private,internal,public,open(3.0),fileprivate(3.0)
这些保护作用域的关键字不能使用在方法内部,class内推荐使用fileprivate
1、private
:作用域在当前的{}
或者文件内
2、fileprivate
:作用域在当前文件,推荐使用
3、internal
:默认作用域
4、public
:可以被任何人访问。但其他module中不可以被override和继承,而在module内可以被override和继承
5、open
:可以被任何人使用,包括override和继承
异常处理
在需要异常处理的函数方法声明后面加throw关键字
在掉该方法的时候使用do{try}catch{}
try
//基本格式
do
{
//没有异常的处理代码
//将try关键字加在有throw关键字说明的函数调用前方空格隔开
}
catch
{
//处理异常,默认的异常存储变量为error
print(error)
}
//json序列化的例子
//1、获取json数据
//1.1获取json路径
let path = NSBundle.mainBundle().pathForResource("MainVCSettings.json", ofType: nil)
//1.2获取json数据
if let jsonPath = path
{
let jsonData = NSData(contentsOfFile: jsonPath)
//1.3json序列化
do
{
let arrJson = try NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers)
// print(arrJson)
//2、便利数组
//swift中便利数组必须告知数组元素都是什么类型
for dict in arrJson as! [[String:String]]
{
// print(dict)
let vcName = dict["vcName"]
let title = dict["title"]
let imageName = dict["imageName"]
addChildViewController(vcName!, title: title!, imageName: imageName!)
}
}
catch
{
//没有服务器数据,创建本地控制器
addChildViewController("HomeTableViewController", title: "首页", imageName:"tabbar_home")
addChildViewController("MessageTableViewController", title: "消息", imageName:"tabbar_message_center")
addChildViewController("DiscoverTableViewController", title: "发现", imageName:"tabbar_discover")
addChildViewController("ProfileTableViewController", title: "我", imageName:"tabbar_profile")
}
}