无法理解这个Swift控制器

时间:2015-08-02 21:02:40

标签: ios swift

我正在学习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!

我理解:我用C​​BCentralManager和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.
    }

这里我给变量centralManager分配了一个CBCentralManager类的实例,但我无法理解为什么我要传递委托。

    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"为什么我有一些具有相同名称但具有不同属性的函数?

谢谢

2 个答案:

答案 0 :(得分:2)

  

这里我给变量centralManager分配了一个实例   CBCentralManager类,但我无法理解为什么我要通过   委派。

您正在分配delegate,以便centralManager知道要拨打电话的人。它使用指向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

答案 1 :(得分:0)

centralManager = CBCentralManager(delegate: self, queue: nil)
Classname(...)初始化该类的实例。在你的代码中,它是一个CBCentralManager类。它将self(你的视图控制器)设置为实例的delegate,这意味着当这个CBCentralManager的实例完成为你的视图控制器做某事时,它会通过一些通过您应在视图控制器中实现的委托方法向视图控制器提供信息。