UIImagePickerController mediaTypes kUTTypeMovie вызывает небольшую утечку памяти в NSCFNumber

Xcode 4.0.2
iPhone4 iOS 4.3.5
Реализованы платформы CoreLocation и MobileCoreServices.
импортировано 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 сообщает о небольших утечках 16 байтов на NSCFNumber, возможном кадре FigRemote_CreatePropertyListFromBinaryPListData:

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

Если я удалю эту линию, утечка исчезнет:

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

Я пробовал это и не избавился от утечки.

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

Утечка происходит сразу после выбора видео и возврата к исходному виду. Есть предположения?


person marshn    schedule 15.08.2011    source источник
comment
почему вы преобразуете константу в строку? не глядя на документы .. это кажется ненужным   -  person Jesse Naugher    schedule 16.08.2011
comment
о, я понял ... думал, что константа может быть примитивной, но это CFStringRef ... хм ... ну, его 16 байтов, честно говоря, это не имеет значения, и откуда это происходит, это похоже на ошибку Apple, когда она внутренне создает список из двоичного списка   -  person Jesse Naugher    schedule 16.08.2011
comment
@marshn Помог ли какой-либо из двух ответов вам решить вашу проблему? Пожалуйста, выберите один из них в качестве принятого ответа.   -  person nodebase    schedule 25.08.2016


Ответы (2)


У меня есть пара утечек по UIImagePickerController, и это была одна из них. Общая утечка составила 208 байт. Я обнаружил, что если типы носителей указаны с использованием кода CoreFoundation C, эта утечка исчезнет.

Итак, утечка следующего кода:

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

Может быть заменен следующим кодом, который не вызывает такой же утечки:

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

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

imagePickerController.mediaTypes = (NSArray*)mTypesArray;

CFRelease(mTypesArray);

Моя теория заключается в том, что оператор утечки не предоставляет информацию, которую предоставляет последний аргумент рабочего кода. kCFTypeArrayCallBacks предоставляет CFArray созданному объекту информацию, необходимую для правильного сохранения и освобождения содержащихся в нем объектов (с использованием CFRetain и CFRelease). Он содержит следующие объекты CFStringRefs... Оператор утечки преобразует эти CFStringRefs в NSStrings, и я думаю, что NSArray использует стандартные сообщения сохранения и выпуска Objective-C для своих объектов.

Эта теория может показаться ложной, потому что CFArray и NSArray подключены бесплатно, и она должна «просто работать». Но пока я придерживаюсь его - это единственное существенное различие между двумя приведенными выше фрагментами кода, которое бросается мне в глаза.

person themacolyte    schedule 13.01.2012

Во-первых, вам необходимо обязательно включить MobileCoreServices Framework в свой проект Xcode, а затем #import <MobileCoreServices/MobileCoreServices.h>, который дает вам доступ к предопределенным константам типа мультимедиа, таким как kUTTypeImage и KUTTypeMovie.

Затем вам нужно знать, что mediaType property ожидает массив, даже если он содержит только один элемент.

Контроллер представления, в который вы помещаете этот код, должен быть делегатом для этих двух: UINavigationControllerDelegate и UIImagePickerControllerDelegate

Затем вы можете поместить этот код где-нибудь, чтобы он был выполнен (например, внутри действия кнопки):

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

Кроме того, в строке 4 моего кода выше, где написано camera.mediaTypes, вы также можете легко сделать это:

camera.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
person nodebase    schedule 20.11.2014
comment
Кодовые ответы должны сопровождаться пояснениями. Пожалуйста, поясните, как / почему это решает проблему. - person Ryan Wheale; 21.11.2014