属性
class Person {
// 存储属性;可提供属性观察方法
var age: Int = 0{
willSet{
print("即将将年龄从\(age) 设置为\(newValue)")
}
didSet{
print("已经将年龄从\(oldValue) 设置为\(age)")
}
}
}
在willSet和didSet中,分别可以使用newValue和oldValue 来获取将要设定的和已经设定的值。
- 计算属性 计算属性则不包括背后的存储,只是提供set和 get 两种方法
class A {
var number: Int {
get{
print("get")
return 1
}
set{
print("set")
}
}
}
类型别名
别名的好处:增强阅读性
typealias Money = Int
struct Page {
// 装 章的数组,元素是 页
typealias Chapter = Array<Page>
// 装书的数组,元素是章
typealias Book = Array<Chapter>
}
typealias Date = (year:Int, month:Int, day:Int)
typealias Success = (Int) -> Int
typealias Failure = (Error) -> Void
typealias Progress = (Double) -> Void
func handle2(success: Success?, failure: Failure?, progress: Progress?) {
// ...
}
/////
final class Dispatcher {
typealias Success = (Int, HTTPResponse) -> Void
typealias Failure = (Error, HTTPResponse) -> Void
private var successHandler: Success?
private var errorHandler: Failure?
func handle(success: Success?, error: Failure?) {
self.successHandler = success
self.errorHandler = error
internalHandle()
}
func handle(success: Success?) {
self.successHandler = success
internalHandle()
}
func handle(error: Failure?) {
self.errorHandler = error
internalHandle()
}
private func internalHandle() {
// ...
}
}
泛型类型别名
typealias MyArray<T> = Array<T> where T: StringProtocol
// MyArray类型的数组 只装遵循StringProtocol协议的元素
单例模式
方式一
final class Users: NSObject {
// 静态变量,内存空间不释放
static let shared = Users()
// 一定要加private防止外部通过init直接创建实例
private override init() {
}
}
方式二
代理/协议
声明协议
@objc
protocol HomeHeaderViewDelegate: class {
associatedtype Money // 声明一个泛型类型(Money具体什么类型在使用时 确定)
func dataDidUpdate() -> Money
// 代理方法(可选)
@objc optional func headerView(_ headerView: UIView, didSelectItemAt index: Int)
// (必须)
func headerViewDidUpdate(_ headerView: UIView )
}
给view 代理属性
class HomeHeaderView: UIView {
// 代理属性 weak修饰
open weak var delegate: HomeHeaderViewDelegate?
// .......
// 点击触发,代理对象执行 代理方法
delegate?.headerView?(self, didSelectItemAt: index)
}
VC遵守协议,设置代理,实现代理方法
lazy var header: HomeHeaderView = {
let v = HomeHeaderView.init()
v.delegate = self // 设置代理
return v
}()
extension HomeController : HomeHeaderViewDelegate{
func headerView(_ headerView: UIView, didSelectItemAt index: Int) {
let mo = self.header.banners![index]
debugPrint("xxxxxx")
}
}
协议中的关键字associatedtype
associatedtype用来定义一个 在协议中的泛型类型。定义为 associatedtype类型的,在实现协议的类中使用的时候,指明该类型的具体类型是什么 即可
协议的扩展extension
可以给协议添加新的函数等,另外可以给协议内部的函数添加 默认实现。
protocol PersonProtocol {
@objc optional var age: Int { get set}
@objc optional func dowork()
}
// 协议扩展
extension PersonProtocol {
// 默认协议方法实现
func dowork(){
print("我想上厕所")
}
// 新增协议方法
func run() {
print("我在跑步")
}
}
通知的使用
监听通知
NotificationCenter.default.addObserver(self, selector: #selector(clickFunc), name: NSNotification.Name.init(rawValue: "xxxName"), object: nil)
//......
// 通知响应方法
@objc func clickFunc(note: NSNotification) {
if let b = note.userInfo?["tag"] as? NSNumber, b == 2 {
}
}
发送通知
NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "xxxName"), object: nil, userInfo: ["tag": 11])
闭包
声明闭包类型,使用时相当于 一个普通类型如:Int、String等,可作为函数入参
typealias actionCallback = (() -> Void)
typealias SwiftBlock = (String,Any) -> Void
调用
actionCallback? ()
testBlock?("ddd","ffffff")
// ps: 不用if判断,那是OC的风格
防止循环引用
{ [weak self] (a,b) in
print(a)
print(b)
}
// [weak self]是为了防止循环引用,(a,b)是传过来的参数
逃逸闭包
就是闭包作为函数的参数,但是在函数结束以后,才去执行这个参数的就叫逃逸闭包。在参数类型前加@escaping
定时器
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in
debugPrint("mm")
}
###动画
UIView.animate(withDuration: 2, animations: {
}) { (end) in
}
线程
主线程异步任务
DispatchQueue.main.async {
}
延迟执行
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0) {
}
self.perform(#selector(popViewController), with: nil, afterDelay: 2.0)
@objc func popViewController(){
}
后台执行
self.performSelector(inBackground: #selector(popViewController), with: nil)
子线程执行方法
self.perform(#selector(doSomething))
关联对象
给类添加新的属性
struct RunTimeViewKey {
static let RunTimeViewID = UnsafeRawPointer.init(bitPattern: "RunTimeViewID".hashValue)
}
extension UIView {
var ViewID: String? {
set {
objc_setAssociatedObject(self, RunTimeViewKey.RunTimeViewID!, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
}
get {
return objc_getAssociatedObject(self, RunTimeViewKey.RunTimeViewID!) as? String
}
}
}