NSObject 类中的委托

Posted

技术标签:

【中文标题】NSObject 类中的委托【英文标题】:Delegation in NSObject Classes 【发布时间】:2017-08-11 07:37:55 【问题描述】:

我在 Viewcontrollers 中使用了委托,它们运行良好,但现在我想要我的两个 NSObject 类之间的委托过程。 但是崩溃了:fatal error: unexpectedly found nil while unwrapping an Optional value

这是我正在做的事情:

基本设备类

class basicDevice : NSObject, CBPeripheralDelegate  
    public static let NOTIFICATION_SERVICES_DISCOVERED = Notification.Name(rawValue: "NOTIFICATION_SERVICES_DISCOVERED")

    private var listOfServices:[String:[String]] = [:]
    private var bleDevice:CBPeripheral?

    func setPheripheral(device:CBPeripheral) 
        bleDevice = device;
        bleDevice!.delegate = self;
    

    func getPheripheral() -> CBPeripheral? 
        return bleDevice;
    

    func getListOfServices() -> [String:[String]] 
        return listOfServices
    

    func onConnected() 
        bleDevice!.delegate = self
        self.bleDevice!.discoverServices(nil)
    

    func onDisconnection() 
        bleDevice!.delegate = nil
    

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) 
        if error != nil  print(" didDiscoverServices:: \(error!)") 
        for service in peripheral.services!
        
            listOfServices[service.uuid.uuidString] = []
            print("Discovered service: \(service.uuid)")
            peripheral.discoverCharacteristics(nil, for: service )
        

        OperationQueue.main.addOperation(
            NotificationCenter.default.post(name: basicDevice.NOTIFICATION_SERVICES_DISCOVERED, object: nil)
        )
    

    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) 
        if error != nil  print(" didDiscoverCharacteristicsFor:: \(error!)") 

        for characteristic in service.characteristics as [CBCharacteristic]!
            listOfServices[service.uuid.uuidString]!.append(characteristic.uuid.uuidString)
        
    


    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) 
        if error != nil  print(" didUpdateValueFor:: \(error!)") 
    


头等舱

protocol DopiSyncCharacteristicDelegate : NSObjectProtocol 
    func dopiSyncCharacteristicData(data : NSData)


 //CBPeripheralDevice(Device API)
class watchBleDevice : basicDevice 

    var dopiSyncCharacteristicDelegate : DopiSyncCharacteristicDelegate!

    override init() 
        super.init()
    

    static func getInstance() -> watchBleDevice 
        if (watchBleDevice.instance == nil) 
            watchBleDevice.instance = watchBleDevice();
        
        return watchBleDevice.instance!;
    

    override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) 
    if error != nil  print(" didUpdateValueFor:: \(error!)") 

    if characteristic.uuid == DipoDopi.dopiStreamCharacteristic.UUID 
        let data:NSData = (characteristic.value as NSData?)!;
        print("dopi stream  data :***********: \(data.hex) : \(data.length) : \(String(describing: data.hexString))")
        dopiStreamCharacteristicDelegate.dopiStreamCharacteristicData(data: data)

    
    super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)


二等

class BluetoothOperations: DopiStreamCharacteristicDelegate

    var watchBleDeviceObject : watchBleDevice!

    override init()
        super.init()
        watchBleDeviceObject = watchBleDevice.getInstance()
        watchBleDeviceObject.dopiCharacteristicDelegate = self
    

    func dopiStreamCharacteristicData(data: NSData) 

    

问题

    是否可以在两个类之间实现委托?怎么样? 这种方法正确吗?如果不是,正确的方法是什么?

谢谢。

【问题讨论】:

我不确定,但我认为它对你有用 ... var watchBleDeviceObject : watchBleDevice = watchBleDevice() 您没有初始化 dopiSyncCharacteristicDelegate 变量。你只是宣布了它。这就是它崩溃的原因。 @jegadeesh 是的,但是如何初始化它以及在哪里? 【参考方案1】:

将第一类的实例传递给第二类。

头等舱

    protocol DopiSyncCharacteristicDelegate : NSObjectProtocol 
        func dopiSyncCharacteristicData(data : NSData)
    

     //CBPeripheralDevice(Device API)
    class watchBleDevice : basicDevice 

    var dopiSyncCharacteristicDelegate : DopiSyncCharacteristicDelegate!

    override init() 
        super.init()
    

    static func getInstance() -> watchBleDevice 
        if (watchBleDevice.instance == nil) 
            watchBleDevice.instance = watchBleDevice();
        
        return watchBleDevice.instance!;
    

    override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) 
    if error != nil  print(" didUpdateValueFor:: \(error!)") 

    if characteristic.uuid == DipoDopi.dopiStreamCharacteristic.UUID 
        let data:NSData = (characteristic.value as NSData?)!;
        print("dopi stream  data :***********: \(data.hex) : \(data.length) : \(String(describing: data.hexString))")
      if(dopiStreamCharacteristicDelegate != nil)
      

     dopiStreamCharacteristicDelegate.dopiStreamCharacteristicData(data: data)
      
      else
       print("delegate is not set yet.")
        // Passing watchBleDevice instance to BluetoothOperations class to set delegates
        BluetoothOperations().initialize(deviceInstance: watchBleDevice.getInstance())
     dopiStreamCharacteristicDelegate.dopiStreamCharacteristicData(data: data)
       

    
    super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
    
    

二等

class BluetoothOperations: NSObject , DipoCharacteristicDelegate, DopiCharacteristicDelegate, DopiSyncCharacteristicDelegate, DopiStreamCharacteristicDelegate

    var dataToDeviceArray:[UInt8] = []
    var getWatchCollectedData: GetWatchCollectedData!
    var watchBleDeviceObject : watchBleDevice!
    private static var instance:BluetoothOperations? = nil;

    static func getInstance() -> BluetoothOperations 
        if (BluetoothOperations.instance == nil) 
            BluetoothOperations.instance = BluetoothOperations();
        

        return BluetoothOperations.instance!;
    
    public func initialize(deviceInstance:watchBleDevice) 
        watchBleDeviceObject = deviceInstance;

        watchBleDeviceObject.dopiSyncCharacteristicDelegate = self
    

func dopiSyncCharacteristicData(data: NSData) 
    print("dopiSyncCharacteristicData : \(data)")


【讨论】:

如何在 watchBleDevice 类中初始化 dopiSyncCharacteristicDelegate ?您发布的代码已经在我的代码中了。 抱歉,您不需要初始化委托对象。你在哪里遇到崩溃?? 在头等舱调用委托函数时。 dopiStreamCharacteristicDelegate.dopiStreamCharacteristicData(data: data) 另外,您也没有在头等舱的任何地方调用 someFunction 方法。但是委托方法调用是在该函数内部调用的。这是故意的吗? 你应该传递一些实际数据。【参考方案2】:

委托模式的基本概念:

protocol SomeDelegate: class 
    func doSomethig()


class FirstClass: NSObject 
    weak var delegate: SomeDelegate?

    func callDelegate() 
        delegate?.doSomethig()
    


class SecondClass: NSObject, SomeDelegate 
    let firstClass = FirstClass()

    override init() 
        super.init()
        firstClass.delegate = self
    

    func foo() 
        firstClass.callDelegate()
    

    // Delegate method
    func doSomethig() 
        print("SecondClass did something")
    


let bar = SecondClass()
bar.foo()

// prints "SecondClass did something"

fatal error: unexpectedly found nil while unwrapping an Optional value 崩溃可能发生在代码的不同位置,因为您总是强制解开可选项——您宁愿使用可选项绑定。

所以回答你的问题: 1.是的,有可能 2. crash发生在哪一行?

【讨论】:

在头等舱调用委托函数时发生的崩溃行。 dopiStreamCharacteristicDelegate.dopiStreamCharacteristicDat‌​a(数据:数据)

以上是关于NSObject 类中的委托的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中单击 NSObject 内部的 tableView 中的项目时,如何在 NSObject 类中的 UIViewController 上的 UIView 之间正确切换?

iOS9如何调用NSObject类中的UIAlertviewController?

NSObject 模态视图和委托

从 viewController 访问 NSObject 类中的 NSMutableArray

如何在 NSObject 类中添加动态行为:Swift

使用 NSObject 的 Swift 2.1 委托