美文网首页
第十七章 Swift 类

第十七章 Swift 类

作者: 我有小尾巴快看 | 来源:发表于2019-06-06 17:08 被阅读0次

Swift 类可以没有基类,自己作为基类则没有super。

class Model {
    
}

class Model1: NSObject {
    
    override init() {
        super.init()
    }
}

class Model2: Model {
    
}

类和结构体相比,拥有继承、动态等能力,并且是引用计数管理内存。

1.创建一个类

创建基类相对继承父类代码要简洁,这里仅用继承父类举例。

class ViewController: UIViewController {
    let fps: Int
    
    init(fps: Int) {
        self.fps = fps
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

上例中创了一个继承UIViewController的类ViewController,他有一个fps属性,在使用super前必须将自身全部属性初始化完毕,然后才能调用父类的designed init

2. 重写父类方法

重写方法必须先加上override关键字,可以通过super调用父类实现。

override func viewDidLoad() {
        super.viewDidLoad()
}

如果父类方法添加了关键字required,则子类必须实现该方法。

required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
}

注意:子类重写的函数和属性,其权限不能小于父类权限。

// error: Overriding property must be as accessible as its enclosing type
override private var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait }

3. 重写父类扩展的方法

扩展的方法必须加上@objc才能被子类重写,重写时也需要加上@objc

extension UIViewController {
    func log() {
        print("UIViewController")
    }
}

extension ViewController {
    // error: Overriding non-@objc declarations from extensions is not supported
   override func log() {
        print("ViewController")
    }
}
extension UIViewController {
    @objc func log() {
        print("UIViewController")
    }
}

extension ViewController {
    @objc override func log() {
        print("ViewController")
    }
}

4. Runtime

Swift类需要使用Runtime则必须继承NSObject以及添加@objc标记,包括要用到的属性。

@objcclass User: NSObject {
    @objc let name: String
    @objc let age: UInt
    
    init(name: String,
         age: UInt) {
        self.name = name
        self.age = age
    }
    
    func keyValues() -> [String: Any] {
        var res = [String: Any]()
        
        var count: UInt32 = 0
        let properties = class_copyPropertyList(self.classForCoder, &count)
        for i in 0..<count {
            guard let property = properties?[Int(i)] else { continue }
            let name = String(cString: property_getName(property))
            let value = self.value(forKey: name)
            res[name] = value
        }
        
        return res
    }
}

如果觉得给每个属性添加@objc比较麻烦,可以添加@objcMembers,这样所有属性都可以被runtime捕捉到。

@objcMembers class User: NSObject {
    let name: String
    let age: UInt
    
    init(name: String,
         age: UInt) {
        self.name = name
        self.age = age
    }
    
    func keyValues() -> [String: Any] {
        var res = [String: Any]()
        
        var count: UInt32 = 0
        let properties = class_copyPropertyList(self.classForCoder, &count)
        for i in 0..<count {
            guard let property = properties?[Int(i)] else { continue }
            let name = String(cString: property_getName(property))
            let value = self.value(forKey: name)
            res[name] = value
        }
        
        return res
    }
}

5. 与OC交互

Swift类导入OC则必须继承NSObject以及添加@objc标记,同时可以利用@objc提供OC专用别用,而OC导入Swift则简单的多。

  • 可以使用@objc重命名
@objc(PKUser) class User: NSObject {

}

@objc(testInOC) func test() {
 
}

@objc(testForOCWithA:orB:andC:) func test(a:Any, b:Any, c:Any) {

}

  • 不想暴露给OC可以添加@nonobjc,但是现在默认不添加@objc了,故@nonobjc仅在@objcMembers下隐藏某些内容有用(之前的版本默认给函数和属性添加@objc,有@objc才会暴露给OC)。
@nonobjc func swiftOnly() {
        
}

6. 引用循环

可以使用weak避免引用循环

weak var delegate: UITableViewDelegate?

在闭包中可以使用unownedweak避免引用循环。(详解在闭包章节)

let block1 = { [unowned self] in
    print(self.view)
}

let block2 = { [weak self] in
    print(self?.view)
}

7. 与OC的不同

  • Swift的资源释放在deinit中完成,dealloc不再被提供。
  • Swift没有load函数

相关文章

  • OC Swift文件混编

    一.Swift 类可以继承 OC 类,OC 类不能继承 Swift 类。 二.Swift 和 OC 混编 三.两个...

  • 第十七章 Swift 类

    Swift 类可以没有基类,自己作为基类则没有super。 类和结构体相比,拥有继承、动态等能力,并且是引用计数管...

  • oc和swift混编 常见问题

    oc调用Swift,import *-Swift.h后,无法调用Swift的类方法Swift的对应类名前增加 @o...

  • Swift中关于NSClassFromString获取不到类

    Swift中关于NSClassFromString获取不到类 当Swift中调用OC写的类 直接 当Swift中调...

  • UI(四十五)Swift

    Swift中没有.h .m文件 Swift中.swift文件 声明实现不在创建 导入类名:不需要再导入类名 所有类...

  • swift 4.2调用系统相册和相机

    界面类, CameraView.swift文件代码: 控制类 ViewController.swift 代码内容:...

  • Swift报错:fatal error: use of unim

    OC与Swift混编时,创建一个swift类继承自OC类,由于这个OC类已自定义构造函数,所以在这个swift类中...

  • iOS - swift

    Swift中没有.h .m文件 Swift中.swift文件声明实现不在创建 导入类名:不需要再导入类名所有类名都...

  • OC和Swift混编遇到的一些小麻烦

    一. OC中调用swift类中的方法时,编译器有时找不到方法声明 OC调用swift类中的方法,swift类需要有...

  • Swift 学习笔记

    初级Swift 记录初级swift学习笔记 1.在Swift中,当需要导入类库的时候,直接输入import + 类...

网友评论

      本文标题:第十七章 Swift 类

      本文链接:https://www.haomeiwen.com/subject/pbprxctx.html