UIAlertView的代表在被解雇之前解除分配

时间:2013-08-10 21:07:48

标签: ios objective-c cocoa-touch automatic-ref-counting uialertview

在我的应用程序中,我有一个单独的对象来处理身份验证并从web服务获取我的应用程序所需的信息以填充表格,我们称之为Getter。

首先我的View Controller我分配了getter

Getter *get = [[Getter alloc]init];
[get getInfoWithCompletion^(id result) {
    if ([result isKindOfClass:[NSMutableArray class]]) {
        NSMutableArray *array = result;
        self.infoarray = array;
        self.tableView.scrollEnabled = TRUE;
        [self.tableView reloadData];
    }
}];

当Getter被告知getinfo时,它会分配一个Downloader对象,告诉它用url下载并给它一个完成块。当下载器完成时,它会调用一个完成块。

Getter.m

- (void)getInfoWithCompletion:(void (^)(id result))completionBlock{
     self.completion = completionBlock;
     Downloader *download = [[Downloader alloc]init];
     [downloader downloadWithURL:@"http://....." completion:^(id results, NSError *error){
            if (error) {
                [self handleErrorWithError:error];
            } else {
                ....
                self.completion(theResult);
            }
     }];

- (void)handleErrorWithError:(NSError *)error {
     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:error.localizedDescription delegate:self cancelButtonTitle:@"Skip" otherButtonTitles:@"Retry",nil];
    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([[alertView buttonTitleAtIndex:buttonIndex]isEqualToString:@"Retry"]) {
    [self getInfoWithCompletion:self.completion];
} else {
    self.completion(nil);
}

这里的问题是,在显示警报视图后,Getter被取消分配,因此当警报尝试告诉代理点击了哪个按钮时,它会崩溃。在ARC之前,你可以在警告之前[自我保留]和委托方法中的[自我发布]。但我无法用ARC做到这一点。或者我可以调用self.completion(错误)并让视图控制器处理它,但让Getter处理它更可重用,所以我不必每次使用它时都复制错误处理代码。由于我无法使用ARC手动保留,如何在显示警报视图后确保Getter保持活动状态?

3 个答案:

答案 0 :(得分:0)

你应该使Getter成为类的属性,并隐式地使用实例变量。

答案 1 :(得分:0)

在ARC中,等同于retain的实例将实例存储到strong属性中。这可以是显式的,也可以通过将其添加到数组(如childViewControllers类的UIViewController)来实现。这样做会使实例保持活动状态,直到你没有属性或从数组中删除实例。

答案 2 :(得分:0)

不要忘记,块在堆栈上分配,因此它们会随着创建它们的上下文消失。如果复制块,则副本将放在堆中,因此它可以在块创建代码返回后生效。我不确定View Controller中分配的块的生命周期是什么,但是如果需要,你可以保持这种方式:

self.completion = [completionBlock copy];