!?编程
?表示可选类型,若是申明属性或变量的话就是默认值为nil的意思,swift
!表示解包,对加!的在使用 前必定要作判nil处理,通常用if let 和 guard let来判断,或者用 if a != nil 来作判断api
闭包的使用闭包
闭包的表达式:async
{(参数)-> 返回值 in函数
//代码spa
}代理
使用例子code
申明为变量:对象
typealias Swiftblock = (String,Any) -> Void
var testBlock: Swiftblock?
复制代码
使用:
testBlock?("ddd","ffffff")
复制代码
实现:
{ [weak self] (a,b) in
print(a)
print(b)
}
[weak self]是为了防止循环引用,(a,b)是传过来的参数
复制代码
逃逸闭包:
就是闭包做为函数的参数,可是在函数结束之后才去执行这个参数的就叫逃逸闭包,在参数类型前加@escaping
逃逸闭包的使用例子
private func requestData(success:@escaping (Any) -> Void) {
DispatchQueue.global().async {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3, execute: {
success("data") //3秒后才执行闭包success
})
}
复制代码
在这个例子中闭包success做为参数,可是他在函数执行完之后过了一段时间才执行,因此他就是逃逸闭包
例子:
requestData { (data) in
let str: String = data as! String //由于data是Any类型的付值给String类型的就须要作类型匹配 ,用as!要确保类型一致且不为nil
print(str)
//或者用as? 来作类型匹配以下
if let stra = data as? String {
print(stra)
}
let strb: String = data as? String ?? ""
print(strb)
guard let strc = data as? String else {
return
}
print(strc)
}
func requestData(success:@escaping (Any) -> Void) {
success("data")
}
复制代码
上面例子中由于参数data是Any类型的付值给String类型的时候就须要作类型匹配
申明函数参数或返回值的时候加?,不然传参数或返回返回值的时候对于可选类型的值要加!
写代理模式的时候
protocol CCDelegate : class {
func doSomething()
}
复制代码
记得在后面加上class关键字,通常加class ,
代理看成变量的时候用weak 修饰防止循环引用
weak var delegate: CCDelegate?
复制代码
if let 和 guard let 的用法,通常用来作非空判断
var some: String?
if some != nil{
print(some!)
}
//或者
guard some != nil else{ return }
print(some!)
//上面的判断用 if let 和guard let 以下
if let aSome = some{
print(aSome)
}
guard let aSome = some else {
return
}
print(aSome)
复制代码
7.swift单例的使用
单例的通常书写格式
class SingleTest {
static let shared = SingleTest()
private init() {} //必定要加private防止外部经过init直接建立实例
}
复制代码
单例的使用例子:
单例类
class SingleTest {
var aValue: NSString?
var bValue: NSString?
static let shared = SingleTest()
private init() {} //必定要加private防止外部经过init直接建立实例
}
单例的使用
SingleTest.shared.aValue = "aaa"
SingleTest.shared.bValue = "bbb"
print("SingleTest.shared.aValue =\(SingleTest.shared.aValue ?? "kong")")
//输出结果为:SingleTest.shared.aValue =aaa
复制代码
.type 是类的类型至关于oc中的Class,
.self 是 静态的在编译时就肯定的类 至关于oc中的class
type(of:) 是实例的类 ,至关于oc 中的 class
例子:
let aa = "aaaa"
let stringMetaType: String.Type = String.self
let stringInstanceType: String.Type = type(of: aa)
print("stringMetaType = \(stringMetaType)")
print("stringInstanceType = \(stringInstanceType)")
if type(of: aa) == String.self {
print("bbbbbbbb")
}
if type(of: aa) is String.Type{
print("cccccc")
}
复制代码
//打印结果以下
stringMetaType = String
stringInstanceType = String
bbbbbbbb
cccccc
从上面的例子能够获得验证
协议的通常书写格式
protocol TestProtocol {
var testVar: Int { get set}
func testFunc()
}
复制代码
Protocol是约定的一种协议,协议中能够有变量,和方法,协议就是一种约定,若是某个对象遵照了该约定就要去实现该约定(协议)的方法和变量(若是遵照了就比如是承诺了就得去实现),协议中方法和变量也能够定义为可选(optional)类型的,若是变量或方法是可选类型的就不须要必定去实现。
协议中方法和变量为可选的protocol格式以下:
@objc protocol TestProtocol {
@objc optional var testVar: Int { get set} //可选
//协议中的变量须要指定 get set
@objc optional func testFunc() //可选
func noOptionFunc() //不可选
}
复制代码
协议的使用
class TestClas: TestProtocol {
//实现协议TestProtocol中的方法
func noOptionFunc() {
print("必定要实现的函数")
}
//实现协议TestProtocol中的方法
func testFunc() {
print("不须要必定实现的函数")
}
}
复制代码
protocol中的 associatedtype关键字
associatedtype用来定义一个在协议中的“泛型”类型 定义为 associatedtype类型的在实现协议的类中使用的时候指明该类型的具体类型是什么就能够了
associatedtype的例子以下
protocol TestProtocol {
associatedtype Num
func testFunc() -> Num
}
class TestClassInt: TestProtocol {
func testFunc() -> Int {
return 1
}
}
class TestClassDouble: TestProtocol {
func testFunc() -> Double {
return 1.666666666
}
}
复制代码
上面例子 TestProtocol中的 Num 被定义为associatedtype,在 TestClassInt和TestClassDouble中用的时候 把Num分别替换为相应的Int 和 Double便可
协议的扩展( Protocol Extension):
协议扩展能够给协议内部的函数添加实现以及给协议添加新的函数等,从而将函数功能添加到遵照协议的全部类型中
例子以下:
@objc protocol Person {
@objc optional var age: Int { get set}
@objc optional func work()
}
extension Person {
func work(){
print("我想上厕所")
}
func run() {
print("我在跑步")
}
}
class Man:Person {
var age: Int = 20
func run() {
print("我是男的也在跑步")
}
}
class Woman: Person {
var age: Int = 18
func work() {
print("去女厕所上厕所")
}
}
let man = Man()
man.work()
man.run()
let woman = Woman()
woman.work()
woman.run()
复制代码
//打印结果以下
//我想上厕所
//我是男的也在跑步
//去女厕所上厕所
//我在跑步
复制代码
上面例子就是对协议扩展的应用
面向协议编程(POP)的理解
简单理解面向协议编程就是用定义协议来代替面向对象编程中的继承多继承等还能达到使用灵活和解偶的目的。
@objc protocol Person {
@objc optional var age: Int { get set}
@objc optional func work()
}
复制代码
//男性
class Man:Person {
var age: Int = 20
func work() {
print("去男厕所上厕所")
}
}
复制代码
//女性
class Woman: Person {
var age: Int = 18
func work() {
print("去女厕所上厕所")
}
}
复制代码
上面例子中定义了一个Person的协议,让Man类和Woman类遵照Person协议就能够达到面向对象编程中继承的效果,若是有多个协议要遵照的话就能够经过遵照多个协议来达到面向对象编程中的多继承的效果
一些基础的总结,有不对的地方还请留言指正