[英]Block leak with __block variable
我发现在requestContentEditingInputWithOptions:
方法中/上发生了很大的内存泄漏。 如果我理解正确,它将与img
变量一起发生。 如果我将其设置为__block __weak
,则在分配图像后该图像__block __weak
nil (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;
}
通过静态分析器运行此代码( shift + command + 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);
}
}];
}
罗伯是对的。 图像可能很大,所以这就是泄漏大的原因。 Core Foundation对象的经验法则是“创建规则”。 在“创建规则”的Xcode中搜索并阅读该文章。 要点是:
Core Foundation函数的名称指示您何时拥有返回的对象:
名称中嵌入“创建”的对象创建函数;
在名称中嵌入了“复制”的对象复制功能。 如果您拥有一个对象,则有责任在完成使用后放弃所有权(使用CFRelease)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.