Dans une application sur laquelle je travaille, il est nécessaire d'interroger périodiquement les données de l'appareil telles que l'accélération, le gyroscope et le mouvement. J'ai écrit la classe suivante pour gérer toutes les tâches connexes (j'utilise également la bibliothèque tierce SOMotionDetector pour détecter si le périphérique est en mouvement, si seulement j'appelle la méthode de délégué didReceiveAcceleration
).Fuite de mémoire potentielle dans le code
import CoreMotion
import Foundation
import SOMotionDetector
protocol MotionManagerDelegate: class {
func didReceiveAcceleration(_ acceleration: (x: Double, y: Double, z: Double))
func didReceiveGyro(_ gyro: (x: Double, y: Double, z: Double))
func didReceiveMotion(_ motion: (x: Double, y: Double, z: Double, w: Double))
}
class MotionManager: NSObject {
weak var delegate: MotionManagerDelegate?
fileprivate let motionDetector = SOMotionDetector.sharedInstance()
fileprivate let accelerationCaptureInterval: TimeInterval = 0.02
fileprivate let gyroCaptureInterval: TimeInterval = 1
fileprivate var lastAcceleration: (x: Double, y: Double, z: Double) = (x: 0.0, y: 0.0, z: 0.0)
fileprivate var isMoving: Bool = false
fileprivate var motionManager: CMMotionManager!
override init() {
super.init()
motionManager = CMMotionManager()
motionManager.gyroUpdateInterval = gyroCaptureInterval
motionManager.accelerometerUpdateInterval = accelerationCaptureInterval
motionManager.deviceMotionUpdateInterval = gyroCaptureInterval
motionDetector?.useM7IfAvailable = true
}
func startCapturing() throws {
motionManager.startGyroUpdates(to: OperationQueue()) { gyroData, error in
if let rotation = gyroData?.rotationRate {
let gyro = (x: rotation.x, y: rotation.y, z: rotation.z)
self.delegate?.didReceiveGyro(gyro)
} else {
let gyro = (x: 0.0, y: 0.0, z: 0.0)
self.delegate?.didReceiveGyro(gyro)
}
}
motionDetector?.motionTypeChangedBlock = { motionType in
if motionType == MotionTypeNotMoving {
self.isMoving = false
} else {
self.isMoving = true
}
}
motionDetector?.startDetection()
motionManager.startAccelerometerUpdates(to: OperationQueue()) { accelerometerData, error in
var x = 0.0
var y = 0.0
var z = 0.0
if let acceleration = accelerometerData?.acceleration {
x = acceleration.x
y = acceleration.y
z = acceleration.z
}
if self.isMoving {
if let delegate = self.delegate {
delegate.didReceiveAcceleration((x: x, y: y, z: z))
}
}
}
motionManager.startDeviceMotionUpdates(to: OperationQueue()) { motionData, error in
if let quaternion = motionData?.attitude.quaternion {
let motion = (x: quaternion.x, y: quaternion.y, z: quaternion.z, w: quaternion.w)
self.delegate?.didReceiveMotion(motion)
}
}
}
func stopCapturing() {
motionManager.stopGyroUpdates()
motionManager.stopAccelerometerUpdates()
motionManager.stopDeviceMotionUpdates()
motionDetector?.stopDetection()
}
}
Cela fonctionne très bien. Mais je reçois des rapports d'erreur aléatoires disant qu'il y a une fuite de mémoire/corruption de tas dans le code. Comme je n'arrive pas à joindre le débogueur et à me déplacer avec l'application en cours d'exécution sur le téléphone, je n'arrive pas à savoir où cela se produit.
J'apprécierais énormément toute aide pour trouver ce que pourrait être le code problématique. Est-ce que l'un de mes codes ci-dessus est sujet à des problèmes comme les cycles de retenue?
Je ne vois pas quelque chose d'évident. Vous pouvez remplacer votre "if let delegate = self.delegate {...}" par la syntaxe que vous avez utilisée ailleurs self.delegate? .didReci ... Sinon, la seule chose que je peux suggérer est d'utiliser les Xcode Instruments , en particulier celui intitulé Leaks. – ekscrypto