Dies ist weniger eine Frage und mehr eine Aufzeichnung dessen, was ich im Zusammenhang mit dem AVCam-Beispielcode von Apple für iOS4 und 5-Kamera-Manipulation gefunden habe. Die Symptome des Problems für mich waren, dass meine App beim Starten des AVCamViewControllers abstürzte, nachdem ich ungefähr 5-10 Fotos gemacht hatte.
Ich habe die App durch den Speicherleck-Profiler laufen lassen und es gab keine offensichtlichen Lecks, aber bei der Überprüfung mit dem Aktivitätsmonitor stellte ich fest, dass etwas namens mediaserverd bei jedem Start der Kamera um 17 MB anstieg und bei einem Wert von ~ 100 MB abstürzte mit mehreren Warnungen für wenig Speicher.
Apple hat den Beispielcode am 17. Oktober 2013 überarbeitet und den Retain-Zyklus festgelegt. Das Problem ist auf eine nicht ordnungsgemäße Verwendung von self
innerhalb der in init
definierten Blöcke zurückzuführen.
Hier ist die Revisionsbeschreibung
Feste Aufbewahrungszyklen in
AVCaptureManager
, die zu Lecks führen. HINWEIS - Wenn SieAVCam
code in Ihrer App angepasst haben, sollten Sie die hier vorgenommenen Korrekturen inAVCaptureManager.m
sinit
method übernehmen. Ohne diese Korrekturen können SieAVCaptureManager
-Instanzen verlieren und die Kamera ständig laufen lassen, während sich Ihre App im Vordergrund befindet.
Allerdings funktioniert die Korrektur, die sie eingeführt haben, nur im Falle der manuellen Retain-Zählung. Wenn Sie ARC für das Projekt verwenden, müssen Sie, abgesehen von der Beseitigung von release
/ retain
-Aufrufen und anderen offensichtlichen Dingen, das Speicherqualifikationsmerkmal für weakSelf
wie folgt von __block
auf __weak
ändern.
Tatsächlich wurde die Semantik von __block
mit ARC geändert. In MRC verursachte dies, dass die Variable schwach referenziert wurde, während dies in ARC nicht der Fall ist und __weak
für diesen Zweck verwendet werden muss.
Weitere Informationen zu diesem Thema finden Sie hier: Wie vermeide ich es, bei der Implementierung einer API Self in Blöcken zu erfassen?
Die Verwendung der neuen init
-Implementierung der letzten Revision und die Verwendung von __weak
anstelle von __block
führten schließlich dazu, dass die dealloc
-Methode ordnungsgemäß aufgerufen wurde.
Endlich, für diejenigen, die es hassen, alten Legacy-Code herumzutragen, ist hier eine modernisierte Version des Projekts AVCam
: Ссылка
Features:
Als erstes habe ich die Dealloc-Methoden aller AVCam-Dateien protokolliert. Ich entdeckte schnell, dass AVCamCaptureManager und AVCamRecorder nicht freigegeben wurden, wenn der AVCamViewController war. Ich überprüfte die Retain- und Release-Calls und sie schienen ausgeglichen zu sein, also legte ich einen Breakpoint auf [captureManager release] und entdeckte, dass es nach der Veröffentlichung einen retainCount von 2 hatte (und daher wurde der dealloc von AVCamCaptureManager nicht aufgerufen) / p>
Als nächstes habe ich den Erstellungsprozess für den Capture-Manager durchlaufen und festgestellt, dass er unmittelbar nach dem Aufruf der init-Methode eine Retain-Zahl von 3 aufweist.
Beim Durchlaufen der init-Methode und Überprüfen der Retain-Anzahl in jeder Zeile erkannte ich, dass die beiden folgenden Zeilen die retain count inkrementieren:
%Vor%Beim Durchsehen habe ich festgestellt, dass die removeObserver-Gegenstücke INNERHALB der dealloc-Methode des AVCamCaptureManager waren (der nicht aufgerufen wurde) und daher die Retain-Anzahl nie auf 0 fiel.
Um es zu beheben, habe ich eine neue Methode public removeObservers erstellt:
%Vor%und dieselben Zeilen aus der Dealloc-Methode von AVCamCaptureManager nehmen.
Aufruf von [captureManager removeObservers]; und dann den Aufruf von [captureManager release]; in der AVCamViewController Dealloc-Methode löscht erfolgreich die Retain-Anzahl auf 0.
Beim Testen mit dem Aktivitätsmonitor wird der MediaServer-Prozess jetzt nur noch bei 5-17MB angezeigt und der Absturz stoppt!
Hoffe das hilft jedem anderen, dieses Problem zu haben!
Vor kurzem ist dieses Problem aufgetreten. Ich stellte fest, dass das eigentliche Grundproblem darin lag, dass DeviceConnectedBlock und DeviceDisconnectedBlock sich implizit auf self bezogen, was zu Retain-Zyklen führte. Um es zu beheben, ändern Sie alle Ivar-Referenzen in diesen Blöcken, um weakSelf zu verwenden.
Auf diese Weise müssen Sie nicht daran denken, eine Teardown-Methode explizit aufzurufen.
Hoffe das hilft jemand anderem.
Tags und Links xcode avcam didreceivememorywarning