Considérez ce code Swift simple qui enregistre datatables de mouvement du périphérique dans un file CSV sur le disque.
let motionManager = CMMotionManager() var handle: NSFileHandle? = nil override func viewDidLoad() { super.viewDidLoad() let documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSSsortingng let file = documents.ssortingngByAppendingPathComponent("/data.csv") NSFileManager.defaultManager().createFileAtPath(file, contents: nil, atsortingbutes: nil) handle = NSFileHandle(forUpdatingAtPath: file) motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler: {(data, error) in let data_points = [data.timestamp, data.attitude.roll, data.attitude.pitch, data.attitude.yaw, data.userAcceleration.x, data.userAcceleration.y, data.userAcceleration.z, data.rotationRate.x, data.rotationRate.y, data.rotationRate.z] let line = ",".join(data_points.map { $0.description }) + "\n" let encoded = line.dataUsingEncoding(NSUTF8SsortingngEncoding)! self.handle!.writeData(encoded) }) }
J'ai été bloqué dessus pendant des jours. Il semble y avoir une fuite de memory, car la consommation de memory augmente régulièrement jusqu'à ce que le operating system suspende l'application pour dépasser les ressources.
Il est essentiel que cette application soit capable de fonctionner pendant de longues périodes sans interruption. Quelques notes:
startDeviceMotionUpdatesToQueue
dans dispatch_async
) ne supprime pas le problème NSOperationQueue
corrige le problème (uniquement lorsque maxConcurrentOperationCount
> = 2). Cependant, cela provoque des problèmes de concurrency lors de l'écriture du file: le file de sortie est brouillé avec des lignes entrelacées entre elles. Des pointeurs? J'ai essayé d'utiliser des instruments, mais je n'ai pas les compétences pour l'utiliser efficacement. Il semble que l'utilisation de la memory qui explose est causée par __NSOperationInternal
. Voici un exemple de trace d'instruments .
Je vous remercie.
D'abord, vois cette réponse de la mienne:
https://stackoverflow.com/a/28566113/341994
Vous ne devriez pas regarder les charts de la memory dans le débogueur; Croyez seulement ce que les Instruments vous disent. Les versions de debugging et les versions Release sont gérées de façon très différente dans Swift.
Deuxièmement, s'il y a encore des problèmes, essayez d'envelopper l'intérieur de votre handler dans une fermeture autoreleasepool
. Je ne m'attends pas à ce que cela fasse une différence, cependant (comme ce n'est pas une boucle), et je ne m'attends pas à ce que ce soit nécessaire, car je suppose que l'utilisation d'Instruments révélera qu'il n'y a jamais eu de problème. . Cependant, l'appel autoreleasepool
s'assurera que les objects autoreleased n'ont aucune chance de s'accumuler.