我正在尝试制作某种谜题,但是在5-10次洗牌后我收到了内存警告,现在我正在尝试添加谜题并将其从超级视图中移除但是,但是,仍然存在某种记忆韭菜..有人可以帮我吗?
- (void)setup6x6
{
int num = 0;
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
UIImageView * imgView = [[UIImageView alloc] init];
cor = arc4random()%4;
nCor = arc4random()%8;
maxCor = arc4random()%16;
scale = _pImage.size.width / puzzleArea.frame.size.width;
NSString * imageName1;
UIImage * imageToMask1;
UIImage * maskedImage1;
if (i == 0)
{
if (j == 0)
{
imageName1 = [topLeftCornerPuzzles objectAtIndex:cor];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake(0,
58 * i * scale,
58 * scale,
58 * scale)];
}
else if (j == 5)
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[topRightCornerPuzzles objectAtIndex:cor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
58 * i * scale,
58 * scale,
58 * scale)];
}
else
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[topPuzzles objectAtIndex:nCor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
58 * i * scale,
66 * scale,
58* scale)];
}
}
else if (i < 5)
{
if (j == 0)
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[leftPuzzles objectAtIndex:nCor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake(0,
(42 + 50*(i-1)) * scale,
58 * scale,
66 * scale)];
}
else if (j == 5)
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[rightPuzzles objectAtIndex:nCor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
(42 + 50*(i-1)) * scale,
58 * scale,
66 * scale)];
}
else
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[middlePuzzles objectAtIndex:maxCor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
(42 + 50*(i-1)) * scale,
66 * scale,
66 * scale)];
}
}
else
{
if (j == 0)
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[bottomLeftCornerPuzzles objectAtIndex:cor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake(0,
(42 + 50*(i-1)) * scale,
58 * scale,
58 * scale)];
}
else if (j == 5)
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[bottomRightCornerPuzzles objectAtIndex:cor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
(42 + 50*(i-1)) * scale,
58 * scale,
58 * scale)];
}
else
{
imageName1 = [self checkPreviousInArray6x6:puzzles new:[bottomPuzzles objectAtIndex:nCor] index:num];
imageToMask1 = [self cropImage:_pImage withRect:CGRectMake((42 + 50*(j-1)) * scale,
(42 + 50*(i-1)) * scale,
66 * scale,
58 * scale)];
}
}
[puzzles addObject:imageName1];
maskedImage1 = [self maskImage:imageToMask1 withMask:[UIImage imageNamed:imageName1]];
[imgView setImage:maskedImage1];
if (i == 0)
originY = 0;
else
originY = 50 * (i-1) + 42;
if (j == 0)
originX = 0;
else
originX = 50 * (j-1) + 42;
if (j == 0 || j == 5)
sizeW = 58;
else
sizeW = 66;
if (i == 0 || i == 5)
sizeH = 58;
else
sizeH = 66;
[imgView setFrame:CGRectMake(originX, originY, sizeW, sizeH)];
[puzzleArea addSubview:imgView];
[imgView removeFromSuperview];
//[maskedImage1 release];
imageToMask1 = nil;
maskedImage1 = nil;
[imgView release];
[imageName1 release];
//[imageToMask1 release];
num += 1;
}
}
}
我有如何裁剪:
- (UIImage *)cropImage:(UIImage *)image withRect:(CGRect)cropRect
{
return [UIImage imageWithCGImage:CGImageCreateWithImageInRect(image.CGImage, cropRect)];
}
还有我掩饰的方式:
- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImg
{
CGImageRef maskRef = maskImg.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef),
NULL,
false);
return [UIImage imageWithCGImage:CGImageCreateWithMask([image CGImage], mask)];
CGImageRelease(maskRef);
CGImageRelease(mask);
}
我无法理解为什么在发布所有内容时会收到内存警告。但是,如果我尝试释放maskedImage1或imageToMask1,我也会收到错误...
答案 0 :(得分:1)
每次创建CGImage
时,都需要发布它。 UIImage
不会为您做到这一点。
如果您没有创建CGImage
,则不应该发布CGImageRelease(maskRef)
。在第二种方法中,您应不执行return
。
当您从方法- (UIImage *)cropImage:(UIImage *)image withRect:(CGRect)cropRect
{
CGImageRef croppedCGImage = CGImageCreateWithImageInRect(image.CGImage, cropRect);
UIImage *croppedUIImage = [UIImage imageWithCGImage:croppedCGImage];
CGImageRelease(croppedCGImage);
return croppedUIImage;
}
- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImg
{
CGImageRef maskRef = maskImg.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef),
NULL,
false);
CGImageRef maskedCGImage = CGImageCreateWithMask([image CGImage], mask);
UIImage *maskedUIImage = [UIImage imageWithCGImage:maskedCGImage];
CGImageRelease(maskedCGImage);
CGImageRelease(mask);
return maskedUIImage;
}
时,不会执行该语句之后的代码。
{{1}}
答案 1 :(得分:1)
经验法则是“释放你拥有的一切”
每当您调用以alloc
,copy
,new
或retain
开头的方法时,您都会获得对象的所有权(这些只是约定,但很多Objective-C是)。
每当您致电release
或autorelease
时,您都会失去对象的所有权。
如果我们使用这些指南查看您的代码,您可以看到您发布了几个您从未拥有的对象。
alloc
然后release
imgView
imageName1
而不分配,复制或保留它。这可能会导致崩溃。 (我假设checkPreviousInArray6x6:new:index:
没有返回它拥有的对象。)对于MaskImage:withMask:
,CG类型遵循类似的规则。
maskRef
永远不会被保留,复制等,因此不应该被释放。mask
正在正确创建和发布。然而,这个方法存在一个很大的问题:return
之后的行永远不会被调用,因此内存永远不会被清除。
我建议在代码上运行静态分析器,因为它有很多错误可以帮助捕获。
有关手动内存管理的完整详细信息,建议您阅读Advanced Memory Management Programming Guide