HealthKit crashing when pulling heart rate on second call after working on first call even when not running any code

筅森魡賤 提交于 2019-12-11 05:57:00

问题


I have a WatchKit app using HealthKit. When a view (with custom WKInterfaceController MonitorMetrics) appears it runs the following code:

    func startRecordingHeartRate() {
    let heartRateSample = HKSampleType.quantityType(forIdentifier:
                                                    HKQuantityTypeIdentifier.heartRate)
    let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
    let datePredicate = HKQuery.predicateForSamples(withStart: Date(), end: nil,
                                                    options: .strictStartDate)

    let anchor: HKQueryAnchor? = nil
    let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> () = {
        [unowned self]
        (query, newResult, deleted, newAnchor, error) in


        if let samples = newResult as? [HKQuantitySample] {
            guard samples.count > 0 else { return }

            for sample in samples {
                print("start of for loop")
                let doubleSample = sample.quantity.doubleValue(for: heartRateUnit)
                let timeSinceStart = sample.endDate.timeIntervalSince(self.startTime)
                heartData[0].append(doubleSample)
                heartData[1].append(Double(timeSinceStart))
                self.delegate?.didRecieveHeartRate()
            }
            print("out of for loop")
            self.updateHeartRateLabel()
        }
    }

    let heartRateQuery = HKAnchoredObjectQuery(type: heartRateSample!,
                                               predicate: datePredicate,
                                               anchor: anchor,
                                               limit: Int(HKObjectQueryNoLimit),
                                               resultsHandler: updateHandler)

    heartRateQuery.updateHandler = updateHandler
    healthStore.execute(heartRateQuery)
}

func updateHeartRateLabel() {
    print("update label")
    let endIndex = heartData[0].endIndex
    let lastHeartRate = heartData[0][endIndex-1]
    self.heartRateLabel.setText(self.nf.string(from:NSNumber(value: lastHeartRate)) ?? "")
}

To pull heart rate data. Once it leaves this view it stops recording heart rate and resets the heartData arrays. When this view appears a second time it runs for one or two heart rates then crashes with a breakpoint on a nopl command in the HealthKit thread. (Since nopl is a no operation command I'm not sure how to interpret a crash there.)

As part of my attempt at debugging I've been commenting out various parts of the code. If I comment out everything in the sample for-loop and self.updateHeartRateLabel() it works without error. If I then uncomment updateHeartRateLabel() it crashes like explained above. Now what is really strange is if I leave the call to updateHeartRateLabel() uncommented but comment out the entirety of the function so it is just

func updateHeartRateLabel() {
}

The program still crashes. But once I commented the call back out it runs fine even though the call isn't doing anything it's still causing a crash. Now if I comment the call back out and uncomment the doubleSample declaration it works but uncommenting the timeSinceStart declaration causes the crash just like before. And the call to the delegate is also causing the crash.

As far as I can tell when I bring the view into view the second time everything should be identical to how it was the first time it was ran. And it runs without problem the second time for one or two heart rate pulls before it crashes. Playing around with it it seems like startTime and delegate just disappear before it crashes. Calling:

print(delegate)

and

print(startTime) 

both cause the crash. And delegate is an optional but the print does not give nil it just crashes as if the variable name "delegate" no longer exists.

Edit:

I never stoped the query with: healthKit.stop(query:). So a Class with several required variables was being deinitialized while updateHandler was still being run leading to it trying to reference non-existing data and crashing.

来源:https://stackoverflow.com/questions/45664116/healthkit-crashing-when-pulling-heart-rate-on-second-call-after-working-on-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!