完成处理程序上的Objective-C EXC_BAD_ACCESS

时间:2018-02-27 17:43:17

标签: ios objective-c

我有一个带有完成处理程序的方法,这就是我调用它的方式:

[dataSource.areaData GetPDFFileData:[NSString stringWithFormat:@"%@",encodedUrlStr] completion:^(NSArray *result, NSError *error) {

//do whatever

}];

但是当我调用这个方法时,我得到一个致命的错误:EXC_BAD_ACCESS我可以看到结果正在填充,这很好,但我不知道我在这里做错了...这里是定义的方法在.h文件中

-(void)GetPDFFileData:(NSString *)PDFFile completion:(void (^) (NSArray * result,NSError * error))completionBlock;

这是我的.m文件中的完整方法:

-(void)GetPDFFileData:(NSString *)PDFFile completion:(void (^) (NSArray * result,NSError * error))completionBlock{


    NSString *FileBrowserRequestString = [NSString stringWithFormat:@"%@?PDFFile=%@",kIP,PDFFile];
    NSURL *JSONURL = [NSURL URLWithString:FileBrowserRequestString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                      {
                                          NSError *myError;
                                          NSArray *tableArray = [[NSArray alloc]initWithArray:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];

                                          completionBlock(tableArray,myError);

                                      }];
    [dataTask resume];

}

我是否错误地调用了完成处理程序?

这是我的回溯:

* thread #2, queue = 'NSOperationQueue 0x16d247f0 :: NSOperation 0x18053ab0 (QOS: LEGACY)', stop reason = EXC_BAD_ACCESS (code=1, address=0x12)
    frame #0: 0x20d93a76 libobjc.A.dylib`objc_msgSend + 22
    frame #1: 0x20da06ae libobjc.A.dylib`objc_storeStrong + 22
  * frame #2: 0x00062428 SchedulingiPadApplication`__51-[LHFileBrowser tableView:didSelectRowAtIndexPath:]_block_invoke((null)=<unavailable>, result=@"1 element", error=0x00000000) at LHFileBrowser.m:183
    frame #3: 0x00066708 SchedulingiPadApplication`__40-[LHJSonData GetPDFFileData:completion:]_block_invoke((null)=0x38739228, data=0x17b17c00, response=0x16f8d710, error=0x00000000) at LHJSonData.m:328
    frame #4: 0x21af3280 CFNetwork`__75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 16
    frame #5: 0x21b02a6a CFNetwork`__49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 278
    frame #6: 0x21dfd678 Foundation`__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 8
    frame #7: 0x21d5e5f2 Foundation`-[NSBlockOperation main] + 146
    frame #8: 0x21d50bc8 Foundation`-[__NSOperationInternal _start:] + 768
    frame #9: 0x21dff930 Foundation`__NSOQSchedule_f + 192
    frame #10: 0x00398492 libdispatch.dylib`_dispatch_queue_drain + 2014
    frame #11: 0x00390de0 libdispatch.dylib`_dispatch_queue_invoke + 284
    frame #12: 0x00399974 libdispatch.dylib`_dispatch_root_queue_drain + 420
    frame #13: 0x003997ce libdispatch.dylib`_dispatch_worker_thread3 + 102
    frame #14: 0x2131db28 libsystem_pthread.dylib`_pthread_wqthread + 1024
    frame #15: 0x2131d718 libsystem_pthread.dylib`start_wqthread + 8

这些是GetPDFFileData

之前的一些代码行
NSString *PDFPath = [[[[self.tableData objectAtIndex:indexPath.row] objectForKey:@"Name"] componentsSeparatedByString:@"FTP\\"] lastObject];

        NSString *encodedUrlStr = [PDFPath urlencode];

        NSString *PDFFile = [[[[self.tableData objectAtIndex:indexPath.row] objectForKey:@"Name"] componentsSeparatedByString:@"\\"] lastObject];

1 个答案:

答案 0 :(得分:-1)

问题似乎是completionBlock未被保留,所以当dataTask完成时,它就不再存在。

您应该保留它,例如将其保留在字典中,然后在任务完成时将其删除。

-(void)GetPDFFileData:(NSString *)PDFFile completion:(void (^) (NSArray * result,NSError * error))completionBlock{

    _completionHandlers[PDFFile] = completionBlock;
    NSString *FileBrowserRequestString = [NSString stringWithFormat:@"%@?PDFFile=%@",kIP,PDFFile];
    NSURL *JSONURL = [NSURL URLWithString:FileBrowserRequestString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                  {
                                      NSError *myError;
                                      NSArray *tableArray = [[NSArray alloc]initWithArray:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];

                                      completionBlock(tableArray,myError);
                                      [_completionHandlers removeObjectForKey:PDFFile];
                                  }];
    [dataTask resume];
}

其中_completionHandlers是您班级中定义的NSMutableDictionary