简体   繁体   中英

Using GCD in performSelectorInBackground: , How this action get an exception?

When I call "performSelectorInBackground" to process some action asynchronously.

My code struct is like:

[self performSelectorInBackground:@selector(AddTheAdditionalDataSourceToTableView) withObject:nil];

and AddTheAdditionalDataSourceToTableView's code struct is like :

-(void)AddTheAdditionalDataSourceToTableView
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    ...
        dispatch_async(dispatch_get_current_queue(), ^{
        ...
        });
    ...
    });
}

and after the viewController call 'popViewController', dealloc will never be called!!!

I know I can just call 'AddTheAdditionalDataSourceToTableView' directly. it will process asynchronously and it works fine. dealloc will called when the viewController did disappear.But I don't know why calling it using "performSelectorInBackground" will cause this exception above.

: (

- (void)reloadTableViewDataSource
{
    //  should be calling your tableviews data source model to reload
    //  put here just for demo
    [self performSelectorInBackground:@selector(reFreshTableView) withObject:nil];
    //[self reFreshTableView];

}

- (void)reFreshTableView
{

NSString *myPoint = [self currentLocationPoint];
if (!myPoint || [myPoint isEqualToString:@""]) {
    [self enableButtons];
    [tableView tableViewDidFinishedLoading];
    return;
}

Interface *interface = [[Interface alloc]init];
/* 默认从page 1开始刷新数据 */
[self disableButtons];

_interface = (id)interface;
interface.delegate = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    [interface aroundInfoFromServiceInterface:_distanceType
                                withTableType:_tableType
                                 withSortType:_sortType
                                  withPageNum:1
                               withNumPerPage:NumberOfCellInOneRequest withPoint:myPoint];
});
//[interface release];
//[tableView flashMessage:@"hahahah"];
}

- (void)aroundInfoFromServiceInterface:(NSInteger)distance
                     withTableType:(NSInteger)tableType
                      withSortType:(NSInteger)sortType
                       withPageNum:(NSInteger)pageNum
                    withNumPerPage:(NSInteger)numPerPage
                         withPoint:(NSString *)myPiont
{

RequestData *data1 = [RequestData requestData:[NSString stringWithFormat:@"%d", distance] key:@"aroundDistant"];
RequestData *data2 = [RequestData requestData:[NSString stringWithFormat:@"%d", tableType] key:@"itemType"];
RequestData *data3 = [RequestData requestData:[NSString stringWithFormat:@"%d", sortType] key:@"sortType"];
RequestData *data4 = [RequestData requestData:[NSString stringWithFormat:@"%d", pageNum] key:@"pageNum"];
RequestData *data5 = [RequestData requestData:[NSString stringWithFormat:@"%d", numPerPage] key:@"numPerPage"];
RequestData *data6 = [RequestData requestData:[NSString stringWithFormat:@"%@", myPiont] key:@"mappoint"];
NSLog(@"%@ , %@ , %@ , %@ , %@ , %@" , [NSString stringWithFormat:@"%d", distance] ,[NSString stringWithFormat:@"%d", tableType] ,[NSString stringWithFormat:@"%d", sortType] ,  [NSString stringWithFormat:@"%d", pageNum], [NSString stringWithFormat:@"%d", numPerPage] , [NSString stringWithFormat:@"%@", myPiont]);
NSArray *tempArray = [NSArray arrayWithObjects:data1, data2, data3, data4, data5, data6, nil];

DataFromService *dataFromService = [[[DataFromService alloc]init]autorelease];

dispatch_async(dispatch_get_main_queue(), ^{

    NSString *strContent = [dataFromService requestData:tempArray fromURL:tableType == 0?AROUND_FRIEND_INFO_URL:AROUND_FISHING_STORE_AND_AREA_INFO_URL];

    NSArray *responseArray = (NSArray *)[self checkRequestResponse:strContent];
    if (responseArray) {
        NSMutableArray *tempArray = [[NSMutableArray alloc]init];
        switch (tableType) {
            case TableType_FrinedsAround:
                tempArray = [[FormatData shareInstance] formatDictToFriendsAround:responseArray];
                break;
            case TableType_FishingStoreAround:
                tempArray = [[FormatData shareInstance] formatDictToFishingStoreAround:responseArray];
                break;
            case TableType_FishingAreaAround:
                tempArray = [[FormatData shareInstance] formatDictToFishingAreaAround:responseArray];
                break;
            default:
                break;
        }

        if (self.delegate && [self.delegate respondsToSelector:@selector(requestDataSuccess:responses:)]) {
            [self.delegate requestDataSuccess:self responses:tempArray];
            return;
        }
    }
});
}
dispatch_get_current_queue()

Gets a background queue, because you are using performSelectorInBackground, it gets called from a background queue.

dispatch_get_main_queue()

dispatch_async returns immediately, so you don't need to use performSelectorInBackground:. You can just call dispatch_async directly:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
...
    dispatch_async(dispatch_get_main_queue(), ^{
    ...
    });
...
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM