Low warning AVCam memory

This is less of a question and more of a report of what I found in the AVCam example code provided by Apple for iOS4 and 5 camera manipulations. The symptoms of the problem for me were that my application would crash when I started AVCamViewController after taking about 5-10 photos.

I ran the application through a memory leak profiler and there were no obvious leaks, but when viewed with the Activity Monitor, I found that something called mediaserverd increases by 17 MB every time the camera starts up and when it reaches ~ 100 MB , the application crashed with several low memory warnings.

+7
source share
3 answers

Apple revised the sample code on October 17, 2013 with a retention cycle. The problem is the misuse of self in blocks defined in init .

Here is the revision description

Fixed saving loops in AVCaptureManager , which lead to leaks. NOTE. If you adapted the AVCam code in your application, you must accept the corrections made here in the AVCaptureManager.m init method. Without these corrections, you can leak instances of AVCaptureManager and leave the camera constantly while your application is in the foreground.


However , the fix they introduced only works with the Manual Retain Count. If you use ARC for a project, in addition to getting rid of release / retain calls and other obvious things, the storage determinant for weakSelf should be changed from __block to __weak , as shown below.

 __weak AVCamCaptureManager *weakSelf = self; 

In fact, __block semantics __block changed using ARC. In MRC, this caused a weak variable indication if ARC does not, and __weak must be used for this purpose.

More information about this topic can be found here: How to avoid capturing yourself in blocks when implementing the API?

Using the new init implementation from the latest version and using __weak instead of __block finally called the dealloc method properly.


Finally, for those who do not like to wear the old old code, here is an upgraded version of the AVCam project: https://github.com/Gabro/AVCam

Features:

  • memory leaks free
  • uses ARC
  • modern Objective-C syntax
  • small user interface fixes for iOS 7
+4
source

The first thing I did was enter the dealloc methods of all the AVCam files. I quickly found that AVCamCaptureManager and AVCamRecorder are not freed when AVCamViewController was. I checked the saved and released calls, and they seemed to be balancing, so I set a breakpoint at the exit [captureManager] and found that it has saveCount from 2 AFTER the release (and therefore dealloc AVCamCaptureManager was not called).

Then I went through the process of creating a capture manager and found that it had a save counter of 3 right after the init method was called.

By executing the init method and checking the amount of hold on each line, I found that the following two lines increase the number of holds:

 [self setDeviceConnectedObserver=[notificationCenter addObserverForName:AVCaptureDeviceWasConnectedNotification object:nil queue:nil usingBlock:deviceConnectedBlock]]; [self setDeviceDisconnectedObserver=[notificationCenter addObserverForName:AVCaptureDeviceWasDisconnectedNotification object:nil queue:nil usingBlock:deviceDisconnectedBlock]]; 

Looking through, I found that the removeObserver copies were INSIDE for the dealloc method for AVCamCaptureManager (which was not called), and therefore the save count never fell to 0.

To fix this, I created a new public removeObservers method:

  -(void)removeObservers { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:[self deviceConnectedObserver]]; [notificationCenter removeObserver:[self deviceConnectedObserver]]; } 

and taking the same OUT strings from the dealloc AVCamCaptureManager method.

Call [captureManager removeObservers]; and THEN calling [captureManager release]; in the dealloc method, the AVCamViewController successfully resets the hold value to 0.

Testing with Activity Activity now has a media camera process that sings just 5-17Mb, and the crash stops!

Hope this helps someone else with this issue!

+16
source

Recently, a problem has arisen. I found that the real root problem was that deviceConnectedBlock and deviceDisconnectedBlock implicitly referred to self, which led to saving loops. To fix this, change all ivar references in these blocks to use weakSelf.

This way, you will not need to explicitly call the teardown method.

Hope this helps someone else.

REF: View the dealloc controller not called when using the NSNotificationCenter code method using ARC

+2
source

All Articles