Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIAlertView';s在取消委派之前取消委派分配_Ios_Objective C_Cocoa Touch_Automatic Ref Counting_Uialertview - Fatal编程技术网

Ios UIAlertView';s在取消委派之前取消委派分配

Ios UIAlertView';s在取消委派之前取消委派分配,ios,objective-c,cocoa-touch,automatic-ref-counting,uialertview,Ios,Objective C,Cocoa Touch,Automatic Ref Counting,Uialertview,在我的应用程序中,我有一个单独的对象来处理身份验证和从Web设备获取我的应用程序需要的信息以填充一个表,我们称之为Getter 因此,首先我分配了视图控制器getter Getter *get = [[Getter alloc]init]; [get getInfoWithCompletion^(id result) { if ([result isKindOfClass:[NSMutableArray class]]) { NSMutableArray *array =

在我的应用程序中,我有一个单独的对象来处理身份验证和从Web设备获取我的应用程序需要的信息以填充一个表,我们称之为Getter

因此,首先我分配了视图控制器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下载,并给它一个完成块。当downloader完成时,它调用一个完成块

盖特

- (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之前,您只需在代理方法中的警报和[self release]之前执行[self retain]。但我不能用ARC做那件事。或者,我可以调用self.completion(error)并让视图控制器处理它,但让Getter处理它更具可重用性,因此我不必每次使用它时都复制错误处理代码。由于我无法使用ARC手动保留,如何确保在显示警报视图后Getter保持活动状态?

您应该将Getter设置为类的属性,并隐式设置为实例变量。

在ARC中,与
保留
相当的是将实例存储到
属性中。这可以是显式的,也可以通过将其添加到数组中(如
UIViewController
类的
childViewControllers
)。执行此操作将使实例保持活动状态,直到您取消属性或从数组中删除实例。

不要忘记,块是在堆栈上分配的,因此它们随创建它们的上下文一起消失。如果复制一个块,那么该副本将被放置在堆中,这样它就可以在创建块的代码返回后继续存在。我不确定在视图控制器中分配的块的生存期是多少,但如果需要,可以通过这种方式保持:

self.completion=[completionBlock copy]