我写了一个从相机获取图像的类。它的标题如下:
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,ImageGetter 的实例在调用后立即被释放-requestImage...
,所以弱的委托picker
就变成了nil
。
解决此类问题的常用方法有哪些?
我可以看到一些方法,但是,它们似乎都不是很正确:
- 从客户端代码中保留 ImageGetter,例如,将其分配给强属性。这里的问题是:我将无法通过在获取图像后立即将此属性设置为 nil 来释放它,因为这意味着在执行此对象的方法时将对象的保留计数设置为 0。另外,我不想要不必要的属性(嗯,这不是一个大问题,但尽管如此)。
- 为 ImageGetter 禁用 ARC 并在启动时手动保留并在将图像发送到回调后释放。
- 制作静态管理器 ImageGetterManager,它将具有方法
requestImage...
,它将创建 ImageGetter 实例,保留它们,重定向requestImage...
调用,从它们获取回调并释放。这似乎是最一致的方式,但是对于这么小的代码来说是不是有点复杂?
那么我怎样才能建立这样一个类呢?