2013-12-16 2 views
0

У моего приложения проблемы с управлением памятью. Я использовал инструменты и заметил, что распределение просто накапливается до тех пор, пока оно не сработает. Я использую ARC. Когда я открываю приложение, он начинается с 97,13 Мб памяти. Я хочу посмотреть, эффективен ли этот фрагмент кода, если есть что-то, что вызывает накопление памяти. Обновление
Согласно Приложению, когда я открываю приложение, приложение использует 93.17mb. Когда я пытаюсь отобразить представление коллекции (OthersViewController) несколько раз, память постепенно увеличивается на 1 мб каждый раз. Сделав снимок (OthersCamera) и вернувшись к контроллеру просмотра, память переместится с 106.87mb до 158.38mb. И странно после этого, когда я пытаюсь снова отобразить изображение (OthersViewController), память просто еще больше поднимается с 158.38 мб до 215.24mb. Получение предупреждения о низкой памяти и сбоя.Извлечение памяти из памяти

Github: https://github.com/canoneoskiss/name/tree/master

+0

когда он падает? после нажатия кнопки? или просто по-своему? Что делает приложение? – CaptJak

+0

Ok Спасибо за комментарий, Мое приложение в основном делает снимок и показывает его в виде коллекции. Он не падает сразу, но если я попытаюсь отобразить представление коллекции несколько раз, то память просто поднимается и поднимается, как гора, и падает. Если вы хотите увидеть конкретный код, скажите мне, я бы с удовольствием поделился им, так как я действительно застрял в этой проблеме. – user3104325

+0

Попробуйте сузить его до тех пор, пока вы не увидите, в какой именно точке вы получаете накопление. Где именно он прыгает? после того, как вы сделаете снимок? когда вы добавляете его в CollectionView? Когда вы показываете вид соединения? – CaptJak

ответ

1

Я посмотрел ваш код, и ваш раскадровка - большой беспорядок. Ваша проблема связана с тем, как вы перемещаетесь между контроллерами. Вы идете назад в раскадровку с помощью segues, и вы не должны этого делать. Когда вы идете назад с помощью segue, вы не возвращаетесь к контроллеру, из которого вы пришли, вы создаете новый экземпляр этого контроллера. За исключением разматывания segues, segues ВСЕГДА создавайте новые контроллеры. Поскольку предъявляющий контроллер и представленный контроллер в модальном сегменте имеют сильные указатели друг на друга, ни один из этих контроллеров никогда не освобождается.

Чтобы исправить это, вам нужно переделать раскадровку. Либо используйте разматывать сегменты, чтобы вернуться назад, либо отклонить любые модальные контроллеры в коде (без каких-либо изменений) с помощью функции shutViewControllerAnimated: завершение :.

+0

Благодарим вас за отличный совет, я никогда не думал о доске объявлений и должен был сфокусироваться на кодировании камеры. Может ли развязать segues использование памяти? – user3104325

+0

@ user3104325, да, они будут, потому что, когда вы идете назад с помощью развязки, контроллер, из которого вы переходите (и между ним и контроллером назначения), будет освобожден, и их память освободится. – rdelmar

+0

@ user3104325, какие действия вы делаете, что вызывает накопление? Я не могу протестировать приложение, так как он должен быть запущен на устройстве для съемки, и у меня нет файлов инициализации для его запуска. Контроллеры в выдвижных ящиках (шляпах, пальто, вершинах и т. Д.) Должным образом освобождаются, когда вы нажимаете кнопку «Назад». ViewController никогда не будет, поскольку это rootViewController контроллера навигации, который является контроллером корневого представления окна. Я не могу проверить кого-либо из других. – rdelmar

0

После захвата изображения изменить его пиксели, потому что в iPhone 1 изображение будет @ 8MB. Даже я столкнулся с этой проблемой. используйте ниже код. после захвата изображения отправьте его этому методу, он вернет изображение с низкой памятью.

+ (UIImage *) croppIngimageByImageName: (UIImage *) imageToCrop toRect: (CGRect) Rect forImageViewRect: (CGSize) imageVwRect {

// UIImage *tempImage; 
// tempImage=[self scaleImage:imageToCrop toSize:imageVwRect]; 

CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect); 
UIImage *cropped = [UIImage imageWithCGImage:imageRef]; 
CGImageRelease(imageRef); 

// cropped=[self scaleImage:cropped toSize:rect.size]; 
return cropped; 

}

или

+ (UIImage *) scaleAndRotateImage: (UIImage *) размер: (интермедиат) MaxSize {

// int kMaxResolution = 640; // Or whatever 

int kMaxResolution = maxSize; // Or whatever 

CGImageRef imgRef = image.CGImage; 

CGFloat width = CGImageGetWidth(imgRef); 
CGFloat height = CGImageGetHeight(imgRef); 

CGAffineTransform transform = CGAffineTransformIdentity; 
CGRect bounds = CGRectMake(0, 0, width, height); 
if (width > kMaxResolution || height > kMaxResolution) { 
    CGFloat ratio = width/height; 
    if (ratio > 1) { 
     bounds.size.width = kMaxResolution; 
     bounds.size.height = roundf(bounds.size.width/ratio); 
    } 
    else { 
     bounds.size.height = kMaxResolution; 
     bounds.size.width = roundf(bounds.size.height * ratio); 
    } 
} 
CGFloat scaleRatio = bounds.size.width/width; 
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); 
CGFloat boundHeight; 
UIImageOrientation orient = image.imageOrientation; 
switch(orient) { 

    case UIImageOrientationUp: //EXIF = 1 
     transform = CGAffineTransformIdentity; 
     break; 

    case UIImageOrientationUpMirrored: //EXIF = 2 
     transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0); 
     transform = CGAffineTransformScale(transform, -1.0, 1.0); 
     break; 

    case UIImageOrientationDown: //EXIF = 3 
     transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height); 
     transform = CGAffineTransformRotate(transform, M_PI); 
     break; 

    case UIImageOrientationDownMirrored: //EXIF = 4 
     transform = CGAffineTransformMakeTranslation(0.0, imageSize.height); 
     transform = CGAffineTransformScale(transform, 1.0, -1.0); 
     break; 

    case UIImageOrientationLeftMirrored: //EXIF = 5 
     boundHeight = bounds.size.height; 
     bounds.size.height = bounds.size.width; 
     bounds.size.width = boundHeight; 
     transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width); 
     transform = CGAffineTransformScale(transform, -1.0, 1.0); 
     transform = CGAffineTransformRotate(transform, 3.0 * M_PI/2.0); 
     break; 

    case UIImageOrientationLeft: //EXIF = 6 
     boundHeight = bounds.size.height; 
     bounds.size.height = bounds.size.width; 
     bounds.size.width = boundHeight; 
     transform = CGAffineTransformMakeTranslation(0.0, imageSize.width); 
     transform = CGAffineTransformRotate(transform, 3.0 * M_PI/2.0); 
     break; 

    case UIImageOrientationRightMirrored: //EXIF = 7 
     boundHeight = bounds.size.height; 
     bounds.size.height = bounds.size.width; 
     bounds.size.width = boundHeight; 
     transform = CGAffineTransformMakeScale(-1.0, 1.0); 
     transform = CGAffineTransformRotate(transform, M_PI/2.0); 
     break; 

    case UIImageOrientationRight: //EXIF = 8 
     boundHeight = bounds.size.height; 
     bounds.size.height = bounds.size.width; 
     bounds.size.width = boundHeight; 
     transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0); 
     transform = CGAffineTransformRotate(transform, M_PI/2.0); 
     break; 

    default: 
     [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; 
} 
UIGraphicsBeginImageContext(bounds.size); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { 
    CGContextScaleCTM(context, -scaleRatio, scaleRatio); 
    CGContextTranslateCTM(context, -height, 0); 
} 
else { 
    CGContextScaleCTM(context, scaleRatio, -scaleRatio); 
    CGContextTranslateCTM(context, 0, -height); 
} 

CGContextConcatCTM(context, transform); 

CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); 
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

return imageCopy; 

}

+0

Похоже, это отличное решение, в котором и куда я должен вставлять этот код? – user3104325

+0

Метод imagepicker будет вызываться, как только вы выберете изображение с камеры или галереи. вы получите изображение в этом методе, вызовите метод, о котором я упоминал, он вернет изображение. вы можете назначить его представлению изображения или изображению и использовать изображение для присвоения представлению изображения –

+0

Итак ... очень запутано. Я должен поместить оба этих кода в othercamera.m ?? Я положил его под метод doReceiveMemoryWarning – user3104325

Смежные вопросы