カメラから画像を取得するクラスを作成しました。そのヘッダーは次のとおりです。
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...
呼び出しがリダイレクトされ、それらからコールバックが取得され、解放されます。これが最も一貫した方法のように思えますが、このような小さなコードでは少し複雑ではありませんか?
では、どうすればそのようなクラスを構築できますか?