我有一个很大的内存泄漏,我已经指出在requestContentEditingInputWithOptions:
方法中发生。如果我理解正确的话会发生img
变量。如果我将其设为__block __weak
,则在我指定(img = [UIImage...])
后图像已经为零。我在某个地方傻吗?或者我如何避免这种内存泄漏?
- (UIImage*) getRightlySizedImgFromAsset:(PHAsset*)asset {
__block UIImage *img;
PHContentEditingInputRequestOptions *coptions = [PHContentEditingInputRequestOptions new];
coptions.canHandleAdjustmentData = ^BOOL(PHAdjustmentData *adjustmentData) { return NO; };
//semaphore used so the block runs synchronously and I can return img from this method at the end
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
[asset requestContentEditingInputWithOptions:coptions completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL* url = [contentEditingInput fullSizeImageURL];
int orientation = [contentEditingInput fullSizeImageOrientation];
CIImage* inputImage = [CIImage imageWithContentsOfURL:url options:nil];
inputImage = [inputImage imageByApplyingOrientation:orientation];
CIContext *context = [CIContext contextWithOptions:nil];
img = [UIImage imageWithCGImage:[context createCGImage:inputImage fromRect:inputImage.extent]];
dispatch_semaphore_signal(sem);
}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
if (needToDoSomethingWithImg){
[self doSomethingWithImage:img];
}
return img;
}
答案 0 :(得分:4)
通过静态分析器运行此代码( shift + 命令 + B 或从“产品”菜单中选择“分析”)它会指出createCGImage
正在创建一个你永远不会发布的CGImageRef
。
您可能想要执行以下操作:
CGImageRef imageRef = [context createCGImage:inputImage fromRect:inputImage.extent];
img = [UIImage imageWithCGImage:imageRef];
CFRelease(imageRef);
顺便说一句,你不应该同步这样做。你应该做点什么:
- (void) getRightlySizedImgFromAsset:(PHAsset*)asset completionHandler:(void (^)(UIImage *))completionHandler {
PHContentEditingInputRequestOptions *coptions = [PHContentEditingInputRequestOptions new];
coptions.canHandleAdjustmentData = ^BOOL(PHAdjustmentData *adjustmentData) { return NO; };
[asset requestContentEditingInputWithOptions:coptions completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL* url = [contentEditingInput fullSizeImageURL];
int orientation = [contentEditingInput fullSizeImageOrientation];
CIImage* inputImage = [CIImage imageWithContentsOfURL:url options:nil];
inputImage = [inputImage imageByApplyingOrientation:orientation];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef imageRef = [context createCGImage:inputImage fromRect:inputImage.extent];
UIImage *image = [UIImage imageWithCGImage:imageRef];
CFRelease(imageRef);
// if this stuff needs to happen on main thread, then dispatch it to the main thread
if (needtodosomethingwithit)
[self doSomethingWithImage:image];
if (completionHandler) {
completionHandler(image);
}
}];
}
答案 1 :(得分:1)
Core Foundation函数的名称表明您拥有的时间 返回的对象:
在名称中嵌入“创建”的对象创建函数;
在名称中嵌入“复制”的对象复制功能。如果 你拥有一个物体,你有责任放弃所有权 (完成后使用CFRelease)。