开发者

UIImagePickerController mediaTypes kUTTypeMovie causes small memory leak in NSCFNumber

开发者 https://www.devze.com 2023-03-28 02:23 出处:网络
Xcode 4.0.2 iPhone4 iOS 4.3.5 CoreLocation and MobileCoreServices frameworks are implemented. imported MobileCoreServices/UTCoreTypes.h

Xcode 4.0.2

iPhone4 iOS 4.3.5

CoreLocation and MobileCoreServices frameworks are implemented.

imported MobileCoreServices/UTCoreTypes.h

- (void) displayVideoPicker
{
    UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
    ipc.sourceType =  UIImagePickerControllerSourceTypePhotoLibrary;
    ipc.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
    ipc.videoMaximumDuration = 45.0f;
    ipc.videoQuality = UIImagePickerControllerQualityTypeMedium;
    ipc.delegate = self;
    [self presentModalViewController:ipc animated:YES];
    [ipc release];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [[picker parentViewController] dismissModalViewControllerAnimated: YES];
}

Instruments is reporting small 16 Bytes leaks on NSCFNumber, possible Frame FigRemote_CreatePropertyListFromBinaryPListData:

Leaked Object   #   Address Size    Responsible Library Responsible Frame
NSCFNumber,8        128 Bytes   MediaToolbox FigRemote_CreatePropertyListFromBinaryPListData

If I remove this line the leak goes away:

ipc.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];

I've tried this and it didn't get rid of the leak.

NSA开发者_开发百科rray *myMediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
ipc.mediaTypes = myMediaTypes;
[myMediaTypes release];

The leak occurs just after picking the video and returning to the initial view. Any thoughts?


I'm getting a couple of leaks around the UIImagePickerController and this was one of them. Total leak was 208 bytes. I found that if the media types are specified using CoreFoundation C code, this leak goes away.

So the following code leaks:

imagePickerController.mediaTypes = [NSArray arrayWithObjects:(NSString*)kUTTypeImage, (NSString*)kUTTypeMovie, nil];

Can be replaced by the following code which does not cause the same leak:

CFStringRef mTypes[2] = { kUTTypeImage, kUTTypeMovie };

CFArrayRef mTypesArray = CFArrayCreate(CFAllocatorGetDefault(), (const void**)mTypes, 2, &kCFTypeArrayCallBacks);

imagePickerController.mediaTypes = (NSArray*)mTypesArray;

CFRelease(mTypesArray);

My theory is that the leaking statement is not providing the information that the final argument of the working code provides. kCFTypeArrayCallBacks provides the CFArray created with the information it needs to properly retain and release the objects it contains (using CFRetain and CFRelease). These objects it contains are CFStringRefs... The leaking statement casts these CFStringRefs to NSStrings and I think the NSArray is using Objective-C standard retain and release messages on its objects.

This theory would seem to be bogus because CFArray and NSArray are toll-free bridged and it should "just work". I'm sticking with it for now though - it's the only significant difference between the two code snippets above that jumps out at me.


First, you need to be sure to include the MobileCoreServices Framework into your Xcode project, then #import <MobileCoreServices/MobileCoreServices.h> which gives you access to the predefined media type constants such as kUTTypeImage and KUTTypeMovie.

Then, you need to know that mediaType property expects an array, even if it contains only one element.

The view controller you are putting this code in needs to be the delegate for these two: UINavigationControllerDelegate and UIImagePickerControllerDelegate

Then you can put this code somewhere to have it be executed (like inside a button action):

UIImagePickerController *camera = [[UIImagePickerController alloc] init];
camera.sourceType = UIImagePickerControllerSourceTypeCamera;
camera.delegate = self;
camera.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
[self presentViewController:camera animated:YES completion:nil];

Also, on line 4 of my code above where it says camera.mediaTypes, you could just easily do this as well:

camera.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
0

精彩评论

暂无评论...
验证码 换一张
取 消