我正在学习Swift,我有一个使用蓝牙来管理BLE外设的控制器。
我无法理解一些细节,完整的代码是here
我在代码之间写我的问题

import UIKit
import CoreBluetooth

class HomeViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate
 {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var stateLabel: UILabel!
    @IBOutlet weak var tempLabel: UILabel!
    var centralManager : CBCentralManager!
    var sensorTagPeripheral : CBPeripheral!

在这里,我明白了:我声明了两个具有CBCentralManager和CBPeripheral类型的变量,现在这两个变量等于nil。
    // IR Temp UUIDs
    let IRTemperatureServiceUUID = CBUUID(string: "F000AA00-0451-4000-B000-000000000000")
    let IRTemperatureDataUUID   = CBUUID(string: "F000AA01-0451-4000-B000-000000000000")
    let IRTemperatureConfigUUID = CBUUID(string: "F000AA02-0451-4000-B000-000000000000")

    override func viewDidLoad() {
        super.viewDidLoad()
        centralManager = CBCentralManager(delegate: self, queue: nil)
        // Do any additional setup after loading the view.
    }

在这里,我将CBCentralManager类的实例分配给变量centralManager,但是我不明白为什么要传递委托。
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func centralManagerDidUpdateState(central: CBCentralManager!) {
        if central.state == CBCentralManagerState.PoweredOn {
            // Scan for peripherals if BLE is turned on
            central.scanForPeripheralsWithServices(nil, options: nil)
            self.stateLabel.text = "Searching for BLE Devices"
        }
        else {
            // Can have different conditions for all states if needed - print generic message for now
            println("Bluetooth switched off or not initialized")
        }
    }

    func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: [NSObject : AnyObject]!, RSSI: NSNumber!) {

        let deviceName = "SensorTag"
        let nameOfDeviceFound = (advertisementData as NSDictionary).objectForKey(CBAdvertisementDataLocalNameKey) as? NSString

        if (nameOfDeviceFound == deviceName) {
            // Update Status Label
            self.stateLabel.text = "Sensor Tag Found"

            // Stop scanning
            self.centralManager.stopScan()
            // Set as the peripheral to use and establish connection
            self.sensorTagPeripheral = peripheral
            self.sensorTagPeripheral.delegate = self
            self.centralManager.connectPeripheral(peripheral, options: nil)
        }
        else {
            self.stateLabel.text = "Sensor Tag NOT Found"
        }
    }

    func centralManager(central: CBCentralManager!, didConnectPeripheral peripheral: CBPeripheral!) {
        self.stateLabel.text = "Discovering peripheral services"
        peripheral.discoverServices(nil)
    }

    func centralManager(central: CBCentralManager!, didDisconnectPeripheral peripheral: CBPeripheral!, error: NSError!) {
        self.stateLabel.text = "Disconnected"
        central.scanForPeripheralsWithServices(nil, options: nil)
    }

    // Check if the service discovered is a valid IR Temperature Service
    func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!) {
        self.stateLabel.text = "Looking at peripheral services"
        for service in peripheral.services {
            let thisService = service as! CBService
            if service.UUID == IRTemperatureServiceUUID {
                // Discover characteristics of IR Temperature Service
                peripheral.discoverCharacteristics(nil, forService: thisService)
            }
            // Uncomment to print list of UUIDs
            //println(thisService.UUID)
        }
    }


    // Enable notification and sensor for each characteristic of valid service
    func peripheral(peripheral: CBPeripheral!, didDiscoverCharacteristicsForService service: CBService!, error: NSError!) {

        // update status label
        self.stateLabel.text = "Enabling sensors"

        // 0x01 data byte to enable sensor
        var enableValue = 1
        let enablyBytes = NSData(bytes: &enableValue, length: sizeof(UInt8))

        // check the uuid of each characteristic to find config and data characteristics
        for charateristic in service.characteristics {
            let thisCharacteristic = charateristic as! CBCharacteristic
            // check for data characteristic
            if thisCharacteristic.UUID == IRTemperatureDataUUID {
                // Enable Sensor Notification
                self.sensorTagPeripheral.setNotifyValue(true, forCharacteristic: thisCharacteristic)
            }
            // check for config characteristic
            if thisCharacteristic.UUID == IRTemperatureConfigUUID {
                // Enable Sensor
                self.sensorTagPeripheral.writeValue(enablyBytes, forCharacteristic: thisCharacteristic, type: CBCharacteristicWriteType.WithResponse)
            }
        }

    }

    func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!) {

        self.stateLabel.text = "Connected"

        if characteristic.UUID == IRTemperatureDataUUID {
            // Convert NSData to array of signed 16 bit values
            let dataBytes = characteristic.value
            let dataLength = dataBytes.length
            var dataArray = [Int16](count: dataLength, repeatedValue: 0)
            dataBytes.getBytes(&dataArray, length: dataLength * sizeof(Int16))

            // Element 1 of the array will be ambient temperature raw value
            let ambientTemperature = Double(dataArray[1])/128

            // Display on the temp label
            self.tempLabel.text = NSString(format: "%.2f", ambientTemperature) as String
        }
    }
}

这基本上是我的问题的核心:我知道协议需要这些功能,但是谁来调用这些功能呢?例如,谁在调用函数“centralManager”,为什么我有一些具有相同名称但具有不同属性的函数?

谢谢

最佳答案

在这里,我为变量CentralManager分配了一个实例
CBCentralManager类,但我不明白为什么要传递
代表。

您正在分配delegate,以便centralManager知道 call 谁。它使用指向您的HomeViewController的指针来调用centralManager*方法。

例如,当centralManager更新状态后,它通过委托指针(即指向viewController的指针)进行调用,从而告诉HomeViewController:

delegate.centralManagerDidUpdateState(central: self)

通过central参数传递一个指向自身的指针。

这基本上是我的问题的核心:我了解这些
协议需要功能,但是谁调用这些功能?
centralManager*函数由centralManager对象调用。它有一个指向HomeViewController的指针。您传递了selfsensorTagPeripheral再次通过您作为peripheral*传递的对象指针self调用delegate函数。

为什么我有一些同名但不同的功能
属性?

它们是不同的功能。它们不同是因为它们具有不同的参数。

在Swift中,函数由它们的名称,参数的数量和类型,其返回类型以及参数的外部名称定义。例如,这是add的两个版本,两个版本都已定义并且都可以被调用。请注意,在调用外部参数名称时会使用它们。这就是Swift区分两个功能的方式:
func add(first x: Int, second y: Int) -> Int {
    return x + y
}

func add(one a: Int, two b: Int) -> Int {
    return a + b
}

let x = add(first: 3, second: 4)
let y = add(one: 3, two: 4)

这是您未曾提出的问题:

centralManager对象如何知道您已经实现了
它要调用的功能?

请注意,当您定义HomeViewController类时,您声明它实现了CBCentralManagerDelegate协议。该协议定义了必须实现的centralManager*函数的接口。如果不这样做,Swift编译器会给您一个错误,指出您不符合CBCentralManagerDelegate。此外,只有实现此协议,才能将self作为委托传递。
class HomeViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate

08-19 12:08