iOS - 访问API返回的数组给出了EXC_BAD_ACCESS(代码= 1)

时间:2014-08-16 13:52:29

标签: ios objective-c memory-management exc-bad-access

我正试图在iOS应用中制作Facebook / 9gag评论页面。简而言之,列表视图中会有一个图像列表,并且有一个评论按钮,当用户按下它时,评论列表视图将像Facebook和9gag中的那样显示。

在我的项目中,我创建了几个实现此目的的类,它们是:

  1. APIOperator,定义要调用的api的路径,并在向服务器发出请求时调用
  2. MyPhotoCell,是一个自定义UITableViewCell类,构成照片列表视图,包含图像和注释按钮
  3. CommentViewController,它是显示评论列表的控制器
  4. CommentCell,这是一个自定义UITableViewCell,形成显示的评论列表
  5. 以下是有关该问题的代码段:

    首先,当用户按下其中一个MyPhotoCell中的注释按钮时,它将调用CommentListViewController的创建:

    //MyPhotoCell.m
    - (void)click_btn_comment:(id)sender 
    {
        CommentViewController *comment_view = [[CommentViewController alloc] initWithNibName:@"CommentViewController" bundle:nil];
        comment_view.targetPhotoid = self.photoItem.photoid;
        [[MyAppCoreData coreData].navController pushViewController:comment_view animated:YES];
    }
    

    以下:

    //CommentViewController.h
    @property (assign, nonatomic) NSInteger targetPhotoid;
    @property (strong, nonatomic) NSMutableArray *arr_commentList;
    
    //CommentViewController.m
    @interface SecondCreation_CommentViewController ()<UITableViewDataSource, UITableViewDelegate>
    {
       ASIHTTPRequest *request_comment;
    }
    
    @property (strong, nonatomic) UITableView *tbl_comment;
    @property (strong, nonatomic) NSNumber *page;
    
    @end
    
    - (void)viewWillAppear:(BOOL)animated
    {
        if(!self.tbl_comment){
            self.tbl_comment = [[UITableView alloc] init];
            self.tbl_comment.delegate = self;
            self.tbl_comment.dataSource = self;
    
            self.tbl_comment.frame = CGRectMake(0, 55, PHOTOWIDTH, SCREEN_HEIGHT - 100);
            [self.view addSubview:self.tbl_comment];
        }
    
        if([NSArray checkEmptyArray:self.arr_commentList]){
            self.page = 0;
            [self sendRequest:1];
        }
    
    }
    
     - (void)addDisplayData:(NSArray *)arr_addData withReset:(BOOL)reset
    {
        //NSLog here shows arr_addData has a count of 6 (6 comments inside, which is normal)
        //NSLog here shows arr_commentList has a count of 0 (which is also expected)
        if (reset) {
            [self.arr_commentList removeAllObjects];
        }else {
            if (!self.arr_commentList) {
                self.arr_commentList = [NSMutableArray array];
            }
        }
        [self.arr_commentList addObjectsFromArray:arr_addData];
        //NSLog here shows arr_addData still has a count of 6
        //NSLog here shows arr_commentList has a count of 6
    }
    
    - (void)sendRequest:(NSInteger)page
    {
        __block typeof(self)blockSelf = self;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            blockSelf -> request_comment = [APIOperator getCommentListForPhoto:@(self.targetPhotoid) andPage:page WithCompletionHandler:^(APISTATUS apiStatus, CommentListItem *commentListItem, ASIHTTPRequest *request) {
                if (request != blockSelf -> request_comment) {
                    return;
                }
                dispatch_async(dispatch_get_main_queue(), ^(void) {
                    if (apiStatus == APISTATUS_SUCCESS) {
                        //I tried to access and print out the content of the returned commentList here, and it gives EXC_BAD_ACCESS (code = 1 ......)
                        //e.g. NSLog(((CommentItem *)[commentListItem.commentList objectAtIndex:0]).message);
    
                        //I tried to assign the returned commentList to my controller through various ways like:
                        //[blockSelf.arr_commentList addObjectsFromArray:commentListItem.commentList];
                        //[blockSelf.arrcommentList = commentListItem.commentList;
                        //[blockSelf addDisplayData:commentListItem.commentList withReset:YES];
                        //I tried to access the content of controller's arr_commentList, it will give EXC_BAD_ACCESS (code = 1, .....) too
                    } else {
    
                    }
                });
            }];
        });
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *identifier = @"commentcell";
        CommentCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    
        if(!cell)
            cell = [[CommentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    
        //acessing the local arr_commentList here will also gives EXC_BAD_ACCESS (code = 1.....)
    
        return cell;
    }
    

    最后,发出api请求的APIOperator类(ASIHTTPREQUEST是一个包装类,用于向服务器发送HTTP请求并与RESTFUL api交互,链接:link here):

    //APIOperator.m
    + (ASIHTTPRequest *)getCommentListForPhoto:(NSNumber *)photoid andPage:(NSInteger)page WithCompletionHandler:(void(^)(APISTATUS apiStatus, CommentListItem *apiItem, ASIHTTPRequest *request))completionBlock
    {
        NSString *str_page = [NSString stringWithFormat:@"%@", @(page)];
        //API_URL here is the url to call the api in the server
        NSString *str_API = [NSString stringWithFormat:@"%@",API_URL];
        ASIHTTPRequest *_request = [ASIHTTPRequest createAPIRequest:str_API];
    
        __block ASIHTTPRequest *request = _request;
        __block void(^tempBlock)(APISTATUS apiStatus, CommentListItem *apiItem, ASIHTTPRequest *request) = completionBlock;
        [_request setCompletionBlock:^{
    
            if ([request responseStatusCode] == 200 || [request responseStatusCode] == 302 || [request responseStatusCode] == 304) {
    
                DEBUGMSG(@"%d %@",[request responseStatusCode], request.url)
                JSONParse *jsonParse = [[JSONParse alloc] initWithData:[request responseData]];
                CommentListItem *obj = (CommentListItem *)[jsonParse parser2OneObject:@"CommentListItem" withPath:nil];
    
                //I tried to print out the contents of the comments here, and everything are as expected
                NSLog(((CommentItem *)[obj.commentList objectAtIndex:0]).message);
    
                jsonParse = nil;
                if (tempBlock) {
                    tempBlock(APISTATUS_SUCCESS,obj,request);
                }
    
                tempBlock = nil;
                request = nil;
    
            } else {
    
                DEBUGMSG(@"%d %@",[request responseStatusCode], request.url)
                if (tempBlock) {
                    tempBlock(apiStatus,nil,request);
                }
                tempBlock = nil;
                request = nil;
            }
    
        }];
        [_request setFailedBlock:^{
    
            DEBUGMSG(@"%d %@",[request responseStatusCode], request.url)
            if (tempBlock) {
                tempBlock(apiStatus,nil,request);
            }
            tempBlock = nil;
            request = nil;
    
        }];
        [_request performSelector:@selector(startAsynchronous)];
    
        return _request;
    }
    

    我在互联网上搜索并发现EXC_BAD_ACCESS代码= 1是关于访问/释放之前已经释放/解除分配的变量,但我仍然无法弄清楚这里的问题。我无法找到它被释放/解除分配的位置,以及为什么它如果被释放/解除分配仍然给我6分。希望我能在这里得到一些帮助,了解导致这个问题的原因以及如何解决这个问题,因为我已经解决了这个问题很长一段时间,但仍然不知道问题是什么以及该怎么做。非常感谢!

0 个答案:

没有答案