UIDeviceBatteryLevelDidChangeNotification不调用选择器函数swift

时间:2015-05-05 16:04:20

标签: ios

以下是更改电池电量时出现此错误的示例代码。你能告诉我哪里出错了。

2015-05-05 21:18:55.383 BatteryStatusTest[1702:204137] -[NSLayoutConstraint batteryLevelChanged:]: unrecognized selector sent to instance 0x170096670
2015-05-05 21:18:55.395 BatteryStatusTest[1702:204137] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSLayoutConstraint batteryLevelChanged:]: unrecognized selector sent to instance 0x170096670'
*** First throw call stack:
(0x1858242d8 0x1970480e4 0x18582b3a4 0x185828154 0x18572accc 0x1857ca2c4 0x185707450 0x186636a80 0x18a29caec 0x1869d5404 0x1857c6dc4 0x1857dba54 0x1857db9b4 0x1857d9934 0x1857052d4 0x18ef1b6fc 0x18a2cafac0x100104bec 0x1976c6a08)
libc++abi.dylib: terminating with uncaught exception of type NSException

但是当我在没有BatterMonitor委托的情况下将此代码放在ViewController.swift中时,它工作正常。

NSNotificationCenter.defaultCenter().addObserver(self, selector: "batteryLevelChanged:", name: UIDeviceBatteryLevelDidChangeNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "batteryLevelChanged:", name: UIDeviceBatteryStateDidChangeNotification, object: nil)

func batteryLevelChanged(notification: NSNotification) {
    //do something
}

示例代码

AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        //Enable Battery Monitor
        UIDevice.currentDevice().batteryMonitoringEnabled = true

        return true
    }
}

ViewController.swift

import UIKit

class ViewController: UIViewController, BatteryMonitorDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        //Battery Monitor before start the drive
        let batteryMonitor = BatteryMonitor()
        batteryMonitor.delegate = self
    }

    func batteyLevelIsNotUnderRecommendedLevel(level: Int) {
        println(level)
    }
}

BatteryMonitor.swift

import UIKit

protocol BatteryMonitorDelegate {
    func batteyLevelIsNotUnderRecommendedLevel (level: Int)
}

struct BatteryMonitorData {
    static let minimumBatteryLevelRequired: Float = 40
}

class BatteryMonitor: NSObject {

    let thisDevice = UIDevice.currentDevice()
    var delegate: BatteryMonitorDelegate?

    override init() {
        super.init()

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "batteryLevelChanged:", name: UIDeviceBatteryLevelDidChangeNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "batteryLevelChanged:", name: UIDeviceBatteryStateDidChangeNotification, object: nil)

        println(UIDevice.currentDevice().batteryLevel)
    }

    func batteryLevelChanged(notification: NSNotification) {
        if thisDevice.batteryLevel <= BatteryMonitorData.minimumBatteryLevelRequired {
            delegate?.batteyLevelIsNotUnderRecommendedLevel(Int(thisDevice.batteryLevel * 100))
        }
    }
}

1 个答案:

答案 0 :(得分:1)

你这里有几个问题......

首先,您要实例化您的BatteryMonitor但不要持有它。

其次,你在BatteryMonitor中保留了对你的委托的强烈引用,这通常是一个坏主意,因为这将导致保留周期

这就是为什么在通知被解雇时,batteryMonitor背后的东西已经是别的了

所以让代表弱,并在BatteryMonitor的deinit中删除你的NSNotification观察......

希望它有所帮助...