我已经开始编写我的第一次认真尝试用于iOS的混合Cordova / Objective-C程序,而且我目前正在尝试关于内存分配的一些绊脚石。我需要让用户的相册艺术在网页视图中显示。我得到了成功展示的艺术,但现在已经分配了大量的内存。
使用"仪器"工具和比较代际快照,我已经将我的罪魁祸首缩小到这些方法 - 我从头开始写这些方法。但我很困惑 - 因为我使用自动引用计数,并且我拥有自动释放池中的所有内容,因此不应该浪费任何内存。有趣的是,我看不到"泄漏"被报告 - 只是一个变大的堆,分配的内存越来越多。
我附上了乐器工具的一些截图:
以下是图片的直接链接,因为文字太多了:
http://i.imgur.com/rkc5dhA.png
http://i.imgur.com/U2esgBT.png
http://i.imgur.com/fmt3Mv4.png
这里是" BukketHelper.M"的内容。我创建的类(匹配标题,没有强大的属性或任何其他任何类型的定义):
-(NSString *) convertULLToNSString:(NSNumber* )guid
{
return [NSString stringWithFormat:@"%llu", [guid unsignedLongLongValue]];
}
-(NSNumber *) convertStringToULL:(NSString *) guid
{
//get string to number
//this causes memory to not be released
unsigned long long ullvalue = strtoull([guid UTF8String], NULL, 10);
NSNumber *numberID = [[NSNumber alloc] initWithUnsignedLongLong:ullvalue];
return numberID;
}
这是" MediaQuery.M"的内容。我创建的类(这与标题完全匹配,没有强大的属性或其他定义):
-(MPMediaItem*) getMediaItemULL:(NSNumber*)guid
{
@autoreleasepool {
//run the query on
MPMediaQuery *query = [[MPMediaQuery alloc] init];
[query addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:guid forProperty:MPMediaItemPropertyPersistentID]];
//get and return the item
NSArray *mediaResults = [query items];
return [mediaResults firstObject];
}
}
-(MPMediaItem*) getMediaItem:(NSString*)guid
{
@autoreleasepool {
BukketHelper* bh = [[BukketHelper alloc] init];
return [self getMediaItemULL:[bh convertStringToULL:guid]];
}
}
-(UIImage*) getMediaAlbumArtAsUIImage:(NSString*)guid withQuality:(NSNumber*)quality withLength:(NSNumber*)length subsituteImageName:(NSString* )filename
{
return [self getMediaAlbumArtFromMediaItemAsUIImage:[self getMediaItem:guid] withQuality:quality withLength:length subsituteImageName:filename];
}
-(NSString*) getMediaAlbumArtAsBase64:(NSString*)guid withQuality:(NSNumber*)quality withLength:(NSNumber*)length subsituteImageName:(NSString* )filename
{
NSString *base64 = nil;
@autoreleasepool {
UIImage* rawImage = [self getMediaAlbumArtAsUIImage:guid withQuality:quality withLength:length subsituteImageName:filename];
NSData *imageData = nil;
if (rawImage != nil)
{
@autoreleasepool {
//this causes memory to not be released
imageData = UIImageJPEGRepresentation(rawImage, [quality floatValue]);
base64 = [imageData base64EncodedStringWithOptions:0];
}
}
}
return base64;
}
-(UIImage*) getMediaAlbumArtFromMediaItemAsUIImage:(MPMediaItem*)item withQuality:(NSNumber*)quality withLength:(NSNumber*)length subsituteImageName:(NSString* )filename
{
UIImage *rawImage = nil;
@autoreleasepool {
bool successfulArt = NO;
if (item != nil)
{
MPMediaItemArtwork *albumArt = [item valueForProperty:MPMediaItemPropertyArtwork];
if (albumArt != nil) {
@autoreleasepool {
//this causes memory to not be released
rawImage = [albumArt imageWithSize:CGSizeMake([length doubleValue], [length doubleValue])];
successfulArt = YES;
}
}
}
if (successfulArt == NO)
{
rawImage = [UIImage imageNamed:filename];
}
}
return rawImage;
}
所以是的 - 我的问题是:在内存分配和泄漏方面,我做错了什么?我目前的测试只使用专辑封面 - 所以" UIImage imageNamed"不应该是问题(来自它的缓存)。另外,我读过ARC无法发布CoreGraphics对象,这也可能是问题所在。
我真的可以用这个帮助!谢谢!
答案 0 :(得分:0)
我遇到了同样的问题。我认为框架中存在一个不释放内存的错误。基本上,每次调用func imageWithSize(size: CGSize) -> UIImage?
时,分配的内存都会出现大幅增长。
如果它对你有帮助,我注意到如果你调用这个函数传入artwork.bounds.size(而不是每次都创建一个新的图像大小),那么内存只被分配一次并再次调用imageWithSize(使用相同的尺寸)不会重新分配新的内存。仅当您传入原始图稿图像的大小而不返回自定义大小时,才会出现这种情况。如果您需要自定义大小,也许您可以自己调整UIImage的大小,而不是依赖于这种错误的方法。