首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在使用计时器从数据库获取更新信息并将其存储在本地数据结构上时,应用程序崩溃

在使用计时器从数据库获取更新信息并将其存储在本地数据结构上时,应用程序崩溃
EN

Stack Overflow用户
提问于 2009-09-23 21:42:16
回答 2查看 751关注 0票数 0

在我们的多用户应用程序中,我们不断地与数据库交互。我们有一个通用的类,通过它我们可以向数据库发送POST查询并返回xml文件。我们使用NSXMLParser的委托来解析获得的文件。我们的问题是,我们面临着许多崩溃,通常当应用程序空闲时,通过每隔几秒钟调用的计时器在后台获取数据库中的更改数据。我们还通过try和catch处理了错误处理,但它在这种情况下被证明是没有用的,并且大多数应用程序崩溃时会出现以下错误:异常类型: EXC_BAD_ACCESS (SIGBUS)异常代码: KERN_PROTECTION_FAILURE at 0x0000000000000020奇怪的是,多次在后台获取更新的数据工作得非常好,相同的方法在类似的条件下成功执行,但在其中一个条件下突然崩溃。我们使用的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// we are using timer in this way:
chkOnlineUser=[NSTimer scheduledTimerWithTimeInterval:15 target:mmObject selector:@selector(threadOnlineUser) userInfo:NULL repeats:YES];


// this method being called in timer
-(void)threadOnlineUser{//HeartBeat in Thread
    [NSThread detachNewThreadSelector:@selector(onlineUserRefresh) toTarget:self withObject:nil];
}

// this performs actual updation
-(void)onlineUserRefresh{
    NSAutoreleasePool *pool =[[NSAutoreleasePool alloc]init];
    @try{
        if(chkTimer==1){
            return;
        }
        chkTimer=1;

        if([allUserArray count]==0){
            [user parseXMLFileUser:@"all" andFlag:3];
            [allUserArray removeAllObjects];
            [allUserArray addObjectsFromArray:[user users]];
        }
        [objHeartBeat parseXMLFile:[loginID intValue] timeOut:10];
        NSMutableDictionary *tDictOL=[[NSMutableDictionary alloc] init];
        tDictOL=[objHeartBeat onLineList];

        NSArray *tArray=[[NSArray alloc] init];
        tArray=[[tDictOL objectForKey:@"onlineuser"] componentsSeparatedByString:@","];
        [loginUserArray removeAllObjects];
        for(int l=0;l less than [tArray count] ;l++){
            int t;//=[[tArray objectAtIndex:l] intValue];
            if([[allUserArray valueForKey:@"Id"] containsObject:[tArray objectAtIndex:l]]){
                t = [[allUserArray valueForKey:@"Id"] indexOfObject:[tArray objectAtIndex:l]];
                [loginUserArray addObject:[allUserArray objectAtIndex:t]];
            }
        }
        [onlineTable reloadData];

        [logInUserPopUp removeAllItems];
        if([loginUserArray count]==1){
            [labelLoginUser setStringValue:@"Only you are online"];
            [logInUserPopUp setEnabled:YES];
        }else{
            [labelLoginUser setStringValue:[NSString stringWithFormat:@"  %d users online",[loginUserArray count]]];
            [logInUserPopUp setEnabled:YES];
        }

        NSMenu *menu = [[NSMenu alloc] initWithTitle:@"menu"];
        NSMenuItem *itemOne = [[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""];
        [menu addItem:itemOne];
        for(int l=0;l less than [loginUserArray count];l++){
            NSString *tempStr= [NSString stringWithFormat:@"%@ %@",[[[loginUserArray objectAtIndex:l] objectForKey:@"user_fname"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]],[[[loginUserArray objectAtIndex:l] objectForKey:@"user_lname"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
            if(![tempStr isEqualToString:@""]){
                NSMenuItem *itemOne = [[NSMenuItem alloc] initWithTitle:tempStr action:NULL keyEquivalent:@""];
                [menu addItem:itemOne];
            }else if(l==0){
                NSMenuItem *itemOne = [[NSMenuItem alloc] initWithTitle:tempStr action:NULL keyEquivalent:@""];
                [menu addItem:itemOne];
            }
        }
        [logInUserPopUp setMenu:menu];

        if([lastUpdateTime isEqualToString:@""]){
        }else {
            [self fetchUpdatedInfo:lastUpdateTime];


            [self fetchUpdatedGroup:lastUpdateTime];// function same as fetchUpdatedInfo
            [avObject fetchUpdatedInfo:lastUpdateTime];// function same as fetchUpdatedInfo
            [esTVObject fetchUpdatedInfo:lastUpdateTime];// function same as fetchUpdatedInfo
        }

        lastUpdateTime=[[tDictOL objectForKey:@"lastServerTime"] copy];
    }
    @catch (NSException * e) {
        [queryByPost insertException:@"MainModule" inFun:@"onlineUserRefresh" excp:[e description] userId:[loginID intValue]];
        NSRunAlertPanel(@"Error Panel", @"Main Module- onlineUserRefresh....%@", @"OK", nil, nil,e);
    }
    @finally {
        NSLog(@"Internal Update Before Bye");
        chkTimer=0;
        NSLog(@"Internal Update Bye");// Some time application crashes after this log

        // Some time application crahses after "Internal Update Bye" log
    }
}

// The method which we are using to obtain updated data is of following form:
-(void)fetchUpdatedInfo:(NSString *)UpdTime{
    @try {
        if(initAfterLoginComplete==0){
            return;
        }

        [user parseXMLFileUser:UpdTime andFlag:[loginID intValue]];
        [tempUserUpdatedArray removeAllObjects];
        [tempUserUpdatedArray addObjectsFromArray:[user users]];
        if([tempUserUpdatedArray count]>0){
            if([contactsView isHidden]){
                [topContactImg setImage:[NSImage imageNamed:@"btn_contacts_off_red.png"]];
            }else {
                [topContactImg setImage:[NSImage imageNamed:@"btn_contacts_red.png"]];
            }
        }else {
            return;
        }
        int chkprof=0;
        for(int l=0;l less than [tempUserUpdatedArray count];l++){
            NSArray *tempArr1 = [allUserArray valueForKey:@"Id"];
            int s;
            if([[[tempUserUpdatedArray objectAtIndex:l] objectForKey:@"Id"] intValue]==profile_Id){
                chkprof=1;
            }
            if([tempArr1 containsObject:[[tempUserUpdatedArray objectAtIndex:l] objectForKey:@"Id"]]){
                s = [tempArr1 indexOfObject:[[tempUserUpdatedArray objectAtIndex:l] objectForKey:@"Id"]];
                [allUserArray replaceObjectAtIndex:s withObject:[tempUserUpdatedArray objectAtIndex:l]];
            }else {
                [allUserArray addObject:[tempUserUpdatedArray objectAtIndex:l]];
            }

            NSArray *tempArr2 = [tempUser valueForKey:@"Id"];
            if([tempArr2 containsObject:[[tempUserUpdatedArray objectAtIndex:l] objectForKey:@"Id"]]){
                s = [tempArr2 indexOfObject:[[tempUserUpdatedArray objectAtIndex:l] objectForKey:@"Id"]];
                [tempUser replaceObjectAtIndex:s withObject:[tempUserUpdatedArray objectAtIndex:l]];
            }else {
                [tempUser addObject:[tempUserUpdatedArray objectAtIndex:l]];
            }
        }

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"user_fname" ascending:YES];
        [tempUser sortUsingDescriptors:[NSMutableArray arrayWithObject:sortDescriptor]];
        [userListTableView reloadData];

        [groupsArray removeAllObjects];
        for(int z=0;z less than [tempGroups count];z++){
            NSMutableArray *tempMArr=[[NSMutableArray alloc] init];
            for(int l=0;l less than [allUserArray count];l++){
                if([[[allUserArray objectAtIndex:l] objectForKey:@"GroupId"] intValue]==[[[tempGroups objectAtIndex:z] objectForKey:@"group_id"] intValue]){
                    [tempMArr addObject:[allUserArray objectAtIndex:l]];
                }
            }
            [groupsArray insertObject:tempMArr atIndex:z];
            [tempMArr release];
            tempMArr= nil;
        }

        for(int n=0;n less than [tempGroups count];n++){
            [[groupsArray objectAtIndex:n] addObject:[tempGroups objectAtIndex:n]];
        }
        [groupsListOV reloadData];
        if(chkprof==1){
            [self profileShow:profile_Id];
        }else {
        }
        [self selectUserInTable:0];
    }@catch (NSException * e) {
        NSRunAlertPanel(@"Error Panel", @"%@", @"OK", nil, nil,e);
    }
}

// The method which we are using to frame select query and parse obtained data is:
-(void)parseXMLForUser:(int)UId stringVar:(NSString*)stringVar{
    @try{

        if(queryByPost)
            [queryByPost release];

        queryByPost=[QueryByPost new];  // common class used to invoke method to send request via POST method

        //obtaining data for xml parsing
        NSString *query=[NSString stringWithFormat:@"Select * from userinfo update_time >= '%@' AND NOT owner_id ='%d' ",stringVar,UId];

        NSData *obtainedData=[queryByPost executeQuery:query WithAction:@"query"];  // method invoked to perform post query

        if(obtainedData==nil){
            // data not obtained so return
            return;
        }

        // initializing dictionary to be obtained after parsing
        if(obtainedDictionary)
            [obtainedDictionary release];

        obtainedDictionary=[NSMutableDictionary new];

        // xml parsing
        if (updatedDataParser) // airportsListParser is an NSXMLParser instance variable 
            [updatedDataParser release]; 

        updatedDataParser = [[NSXMLParser alloc] initWithData:obtainedData];
        [updatedDataParser setDelegate:self]; 
        [updatedDataParser setShouldResolveExternalEntities:YES]; 

        BOOL success = [updatedDataParser parse];  

    }
    @catch (NSException *e) {
        NSLog(@"wtihin parseXMLForUser- parseXMLForUser:stringVar: - %@",[e description]);
    }

}
//The method which will attempt to interact 4 times with server if interaction with it is found to be unsuccessful , is of following form:
-(NSData*)executeQuery:(NSString*)query WithAction:(NSString*)doAction{
    NSLog(@"within ExecuteQuery:WithAction: Query is: %@ and Action is: %@",query,doAction);
    NSString *returnResult;
    @try {

        NSString *returnResult;
        NSMutableURLRequest *postRequest;
        NSError *error;
        NSData *searchData;
        NSHTTPURLResponse *response;
        postRequest=[self directMySQLQuery:query WithAction:doAction];  // this method sends actual POST request

        NSLog(@"after directMYSQL in QueryByPost- performQuery... ErrorLogMsg");
        searchData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&error];
        returnResult = [[NSString alloc] initWithData:searchData encoding:NSASCIIStringEncoding];

        NSString *resultToBeCompared=[returnResult stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        NSLog(@"result obtained - %@/ resultToBeCompared - %@",returnResult,resultToBeCompared);


        if(![resultToBeCompared isEqualToString:@""]){
        }else {
            sleep(10);
            postRequest=[self directMySQLQuery:query WithAction:doAction];
            searchData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&error];
            if(![resultToBeCompared isEqualToString:@""]){
            }else {
                sleep(10);
                postRequest=[self directMySQLQuery:query WithAction:doAction];
                searchData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&error];
                if(![resultToBeCompared isEqualToString:@""]){
                }else {
                    sleep(10);
                    postRequest=[self directMySQLQuery:query WithAction:doAction];
                    searchData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&error];
                    if(![resultToBeCompared isEqualToString:@""]){
                    }else {
                        sleep(10);
                        postRequest=[self directMySQLQuery:query WithAction:doAction];
                        searchData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&error];
                        if(![resultToBeCompared isEqualToString:@""]){
                        }else {
                            return nil; 
                        }
                    }
                }
            }
        }




        returnResult = [[NSString alloc] initWithData:searchData encoding:NSASCIIStringEncoding];

        return searchData;
    }
    @catch (NSException * e) {
        NSLog(@"within QueryByPost , execurteQuery:WithAction - %@",[e description]);
        return nil;     
    }
}

// The method which sends POST request to server , is of following form:
-(NSMutableURLRequest *)directMySQLQuery:(NSString*)query WithAction:(NSString*)doAction{   
    @try{
        NSLog(@"Query is: %@ and Action is: %@",query,doAction);

        // some pre initialization
        NSString *stringBoundary,*contentType;
        NSURL *cgiUrl ;
        NSMutableURLRequest *postRequest;
        NSMutableData *postBody;
        NSString *ans=@"434";

        cgiUrl = [NSURL URLWithString:@"http://keysoftwareservices.com/API.php"];
        postRequest = [NSMutableURLRequest requestWithURL:cgiUrl];
        [postRequest setHTTPMethod:@"POST"];

        stringBoundary = [NSString stringWithString:@"0000ABCQueryxxxxxx"];
        contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", stringBoundary];
        [postRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];

        //setting up the body:
        postBody = [NSMutableData data];
        [postBody appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"code\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:ans] dataUsingEncoding:NSUTF8StringEncoding]];

        [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"action\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:doAction] dataUsingEncoding:NSUTF8StringEncoding]];

        [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"devmode\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"devmode"]] dataUsingEncoding:NSUTF8StringEncoding]];

        [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"q\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:query] dataUsingEncoding:NSUTF8StringEncoding]];

        [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postRequest setHTTPBody:postBody];

        NSLog(@"Direct My SQL ok");// Some time application crashes afte this log

        //Some time application crashes after "Direct My SQL ok" log
        return [postRequest mutableCopy];

    }@catch (NSException * e) {
        NSLog(@"NSException %@",e);
        NSRunAlertPanel(@"Error Panel", @"Within QueryByPost- directMySQLQuery...%@", @"OK", nil, nil,e);
        return nil;
    } 
}
EN

回答 2

Stack Overflow用户

发布于 2009-09-23 21:48:38

EXC_BAD_ACCESS是一个硬错误。这不是一个异常,你不可能捕捉到它。

这意味着你的代码做了一些尝试访问无效内存的事情。最有可能的是,通过尝试取消引用一个被丢弃的指针。过度发布是实现这种崩溃的一种常见方式。

在这种情况下,崩溃的原因很可能是因为您正在敲击来自后台线程的用户界面对象。除非文档明确说明它是线程安全的,否则任何东西都不是线程安全的,即使这样,您可以从线程执行的操作也可能存在限制。

考虑到缺乏适当的线程模型的致命后果,我没有仔细研究代码的其余部分。然而,内存管理存在一些明显的问题;泄漏和可能的一两个过度释放。

我的建议是完全重写这段代码。首先,考虑如何沿着模型-视图-控制器MVC线来分解问题。考虑是否可以使用NSURL*和NSHTTP*类进行客户端/服务器通信--如果可以,可以将它们配置为异步进行通信。

就线程而言,您需要非常仔细地考虑如何划分问题;如何在不对主线程执行线程不安全操作的同时将位移出主线程。

票数 1
EN

Stack Overflow用户

发布于 2010-06-14 03:53:23

试试Matt Gallaghers励志的uncaughtexceptionhandler吧。http://cocoawithlove.com/2010/05/handling-unhandled-exceptions-and.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1469925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文