代码之家  ›  专栏  ›  技术社区  ›  Laurence Wingo

协议在Swift中是引用类型还是值类型?

  •  1
  • Laurence Wingo  · 技术社区  · 6 年前

    我问这个问题的原因是因为我正在阅读一个使用委托的教程。根据我在网上读到的其他教程/文章,据我所知,这个特定的教程并没有创建一个保留周期。我还通过使用工具(内存泄漏和僵尸)来测试它,以确保没有内存泄漏。

    我试图弄清楚,如果一个类只是要符合一个协议,这会创建一个引用吗?

    我想不会,但我想确定一下。

    以下是创建委托成员的协议和类:

    import Foundation
    import CoreBluetooth
    
    protocol TransferServiceScannerDelegateProtocol: NSObjectProtocol {
        func didStartScan()
        func didStopScan()
        func didTransferData(data: NSData?)
    }
    
    class TransferServiceScanner: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
        var centralManager: CBCentralManager!
        var discoveredPeripheral: CBPeripheral?
        var data = NSMutableData()
        weak var delegate: TransferServiceScannerDelegateProtocol?
    
        init(delegate: TransferServiceScannerDelegateProtocol?) {
            super.init()
            centralManager = CBCentralManager(delegate: self, queue: nil)
            self.delegate = delegate
        }
    
    
        //start of cbCentralDelegate method
        func centralManagerDidUpdateState(_ central: CBCentralManager) {
            switch central.state {
            case .poweredOn:
                print("Central is powered on...")
                break
            case .poweredOff:
                print("Central is powered off...")
                break
            default:
                print("Central manager changed state \(central.state)")
                break
            }
        }
        //end of cbCentralDelegate method
    
    }
    

    import UIKit
    
    class CentralViewController: UIViewController, TransferServiceScannerDelegateProtocol {
        @IBOutlet var heartImage: UIImageView!
        @IBOutlet var scanButton: CustomButton!
        @IBOutlet var textView: UITextView!
        var transferServiceScanner: TransferServiceScanner!
    
        // MARK: TransferServiceScannerDelegateProtocol methods
        func didStartScan() {
            //
        }
    
        func didStopScan() {
            //
        }
    
        func didTransferData(data: NSData?) {
            //
        }
        //end of TransferServiceScannerDelegateProtocol methods
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            transferServiceScanner = TransferServiceScanner.init(delegate: self)
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
    
        /*
        // MARK: - Navigation
    
        // In a storyboard-based application, you will often want to do a little preparation before navigation
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            // Get the new view controller using segue.destinationViewController.
            // Pass the selected object to the new view controller.
        }
        */
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Fabian    6 年前

    我不认为这会增加参考计数:

    var transferServiceScanner: TransferServiceScanner

    将委托变量存储为 weak 确保强引用不是双向的,这样ARC就可以对它们进行删除。

    我试图弄清楚,如果一个类只是要符合一个协议,这会创建一个引用吗?

    类始终是引用类型,无论您是通过协议还是直接引用它。因此,在一个协议后面指定一个引用类型(class)并不会复制class对象,而是给出另一个对该对象的引用,并增加ARC所看到的引用计数。

    protocol TransferServiceScannerDelegateProtocol: NSObjectProtocol {
    

    weak var delegate: TransferServiceScannerDelegateProtocol ,因为只有类可以实现 NSObjectProtocol NSObject &公司。

    虚弱的 用它。