我写了一个类,可以从相机中获取图像。其标题如下:
typedef void(^ImageTakenCallback)(UIImage *image);
@interface ImageGetter : NSObject <UIImagePickerControllerDelegate, UIPopoverControllerDelegate>
{
UIImagePickerController *picker;
ImageTakenCallback completionBlock
}
-(void) requestImageInView:(UIView*)view withCompletionBlock:(void(^)(UIImage*))completion;
@end
如您所见,我正在尝试在客户端代码中做类似的事情:
[[[ImageGetter alloc] init] requestImageInView:_viewController.view withCompletionBlock:^(UIImage *image) {
// do stuff with taken image
}];
这是我实现ImageGetter的方式:
-(void) requestImageInView:(UIView*)view withCompletionBlock:(ImageTakenCallback)completion
{
completionBlock = [completion copy];
picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.delegate = self;
[view addSubview:picker.view];
}
- (void)imagePickerController:(UIImagePickerController *)picker_
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
[picker.view removeFromSuperview];
picker = nil;
completionBlock(image);
}
问题是,由于我使用的是ARC,因此在调用
-requestImage...
后立即释放了ImageGetter实例,因此picker
的弱委托变成了nil
。解决此问题的常用方法有哪些?
我可以看到一些方法,但是,似乎没有一种是正确的:
requestImage...
方法,它将创建ImageGetter实例,保留它们,重定向requestImage...
调用,从它们获取回调并释放。这似乎是最一致的方法,但是对于这样的少量代码来说是否有点复杂? 那么我该如何建立这样的 class 呢?
最佳答案
您可以在ImageGetter
类中通过创建和释放“自引用”来解决该问题。
在实现文件的类扩展中,声明一个属性
@interface ImageGetter ()
@property (strong, nonatomic) id selfRef;
@end
在
requestImageInView:
中,设置self.selfRef = self
以防止取消分配。在完成方法中,设置
self.selfRef = nil
。备注:实际上,即使使用ARC,您也可以管理保留计数:
CFRetain((__bridge CFTypeRef)(self)); // Increases the retain count to prevent deallocation.
CFRelease((__bridge CFTypeRef)(self)); // Decreases the retain count.
但是我不确定这是否被认为是ARC的“良好编程”。
欢迎任何反馈!