首页 > 解决方案 > 为什么我的 Swift iOS 构建会出错:“在范围内找不到‘睡眠’”

问题描述

.swift 文件是 iOS ObjC 静态库的一部分。当我尝试构建时,我得到构建错误。

睡眠是因为我想确保停止扫描完成,然后想完全优雅地拆除 CBCentralManager。

import UIKit
import CoreBluetooth
import os  

    // Instantiate BLE central service:
    var BLE_Central_instance = BLE_Central();

 . . .  


    // Tears down BLE central
    public func stop_BLE_Central()
    {
        os_log("BLE_Central: stop_BLE_Central...")     
        BLE_Central_instance.stop_CBCentralManager()
        os_log("BLE_Central: stop_BLE_Central done.")
    }

. . .  

    @objc open class BLE_Central: NSObject
    {  
    . . .  
        @objc public func stop_CBCentralManager()                           
        {
           os_log("BLE_Central: stop_CBCentralManager...")     
            
            centralManager.stopScan()
            os_log("        Scanning stopped (ie. centralManager)")
    
            Sleep(5)
    
            centralManager = nil 
    
            data.removeAll(keepingCapacity: false)
            
     
            os_log("BLE_Central: stop_CBCentralManager done.")
       }

标签: iosswiftcore-bluetoothcbcentralmanager

解决方案


通过这里的各种方法,

Sleep(5)

这不起作用,因为没有这样的功能Sleep()。可以通过使用来解决这个问题

Thread.sleep(forTimeInterval: 5)

这样可以避免错误,但由于几个原因,它的设计确实很糟糕。第一个是你阻塞线程5秒,从外观上看,它是主线程。在此期间,这完全锁定了您的用户界面。如果主线程被阻塞,则没有 UI 元素可以响应。

你可以通过使用类似的东西来避免这种情况

DispatchQueue.main.asyncAfter(deadline: .now() + 5) { 
    // Do delayed stuff here
}

这不会阻塞当前线程,它说,现在继续运行,但在 5 秒内完成这些工作。所以这更好,或者至少不那么糟糕。

这里是一个糟糕的想法的第二个原因Thread.sleep是,它是一种糟糕的创可贴。不能保证 5 秒是正确的时间量。可能太多,也可能太少。您需要的时间量可能不一致。您希望 5 秒就足够了,但您无法知道这一点。

更好的方法是寻找你真正想知道的东西。您正在使用CBCentralManager并且想知道它何时停止扫描。所以,当它的值从变为时,使用isScanning属性并做你的事情。CBCentralManagertruefalse

首先,确保@objc在您的中央管理器声明中使用,并添加一个观察属性:

@objc fileprivate(set) var central: CBCentralManager
var observation: NSKeyValueObservation?

然后注册已更改的通知isScanning,并处理这些更改:

    observation = observe(\.central.isScanning, options: NSKeyValueObservingOptions.new) { (manager, change) in
        guard let isScanning = change.newValue else { return }
        if !isScanning {
            // Do your delayed stuff here
        }
    }

推荐阅读