2011-04-30 4 views
0

참고 : 문제는이 코드에 없지만 EXC_BAD_ACCESS에 대한 대답은 @strange가 말한 내용입니다.EXC_BAD_ACCESS 응용 프로그램을 다시 시작하고 reloadTable을 호출하십시오.

viewForHeaderInSection 메서드가 호출 된 후에이 EXC_BAD_ACCESS가 발생합니다. 지금 내가 마지막 몇 시간 동안 디버깅을했기 때문에 처음으로 테이블이로드 될 때 호출되는 메서드의 순서가 달라집니다.

참고 : 각 행에는 2 개의 섹션이 있습니다.

  1. numberOfSectionsInTableView
  2. viewForHeaderInSection
  3. heightForRowAtIndexPath (제 1, 로우 0)
  4. viewForHeaderInSection (제 1)
  5. numberOfRowsInSection (제 1)
  6. heightForHeaderInSection (제 1) (섹션 0)
  7. heightForHeaderInSection (섹션 0)
  8. ,515,
  9. numberOfRowsInSection
  10. heightForRowAtIndexPath (제 0, 로우 0)
  11. cellForRowAtIndexPath (제 0, 로우 0)
  12. cellForRowAtIndexPath (제 1, 행 0)
  13. viewForHeaderInSection (섹션 0) 다음 (섹션 1)
  14. viewForHeaderInSection

그리고 (섹션 0) 내 테이블이 제대로 표시 얻을.

는 지금은

[self.tableView reloadTable] 

위의 모든 (13 개)의 방법이 동일한 순서로 호출되는 전화를하지만 숫자 뒤에 (13) 내 코드는 EXC_BAD_ACCESS을 보여주는 다음 줄

int retVal = UIApplicationMain(argc, argv, nil, nil); 

에 main 메소드로 이동 .

환경 변수에 NSZombie를 사용할 수는 있지만 도움이되지 않아 할당과 좀비 계측을 시도했지만 아무 것도 알아 내지 못했습니다.

도움이 될 것입니다.

편집 : 섹션 헤더과 내가 cell.contentView에있는 CustomView를 추가하고에있는 CustomView를

EDIT2 : 혼란을 드려 죄송합니다 사람이의 reloadTable이 제대로이 예외가 다른 곳에서오고 실행됩니다, 나는 아직도 어디에서 찾으려고 노력하고있다.

EDIT3 : 안녕하세요, 내가 시뮬레이터에서 응용 프로그램을 삭제하고 시뮬레이터에서 응용 프로그램을 삭제하고 xcode에서 신선한 것을 설치하면 새로운 정보를 얻을 수 있습니다. 그리고 엑스 코드를 통해 다시 실행, 내가 NSZombie

내가 reloadTable 곳 후
[CALayer retainCount]: message sent to deallocated instance 0x19384fd0 

에 다음과 같은 오류 메시지가, 그 오류가 오는 곳 정확히 모르겠습니다.

(GDB) 포 0x19384fd0 2011-05-01 07 : 08 : 06.194 아삭 [51,635 : 207] * - [의 CALayer respondsToSelector는 :] 메시지가 해제 된 경우에 전송 0x19384fd0

프로그램 수신 신호 SIGTRAP , 추적/중단 점 트랩. 0x012f1657 in 포워딩() 디버깅중인 프로그램은 GDB에서 호출되는 함수에서 신호를받습니다. GDB는 호출하기 전의 컨텍스트를 복원했습니다. 이 동작을 변경하려면 "unwindonsignal 설정 해제"를 사용하십시오. 함수 (_NSPrintForDebugger)가 포함 된 식의 평가가 취소됩니다. (GDB) 역 추적

0 0x012f1657 CFGetRetainCount() CA에서

3 0x000d9dc1에 forwarding_prep_0_()

2 0x012bf990에()

1 0x012f1522 전달 에서 : : release_root_if_unused()

4 0x0015830f x_hash_table_remove_if() CA에서

5 0x000da246에 :: 트랜잭션 :()

CA에서

6 0x000da46d : 트랜잭션 :: observer_callback() CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION()

에서

7 0x0136189b 커밋 __CFRunLoopDoObservers()에 __CFRunLoopRun

0x012bf1d7()

8 0x012f66eGSEventRun() UIApplicationMain에

14 0x004a1c93 (에 GSEventRunModal()

13 0x01ec7289에 CFRunLoopRunInMode()

12 0x01ec71c4에 CFRunLoopRunSpecific()

11 0x012be761에

10 0x012be840)

15 main.m의 주 (argc = 1, argv = 0xbfffef2c)의 0x000025d4 : 13

흐름의 순서가 끝나면이 예외가 발생합니다.

비동기 nsurlconnection을 실행 중입니다. connectionDidFinishLoading에서 응답을 받으면 메소드를 호출하여 해당 데이터를 데이터베이스에 저장합니다. saveData 메소드에서 saveData 메소드로 saveData 메소드를 호출합니다. 부울 변수를 설정합니다. 내보기 컨트롤러의

dataSaved = YES 

두 빨리 YES로 변수 집합으로이 부울 변수를 관찰하는 (그 안에 테이블을 가지고), 그리고 두 뷰 컨트롤러는 자신의

(void)observeValueForKeyPath:(NSString *)keyPath 
        ofObject:(id)object 
        change:(NSDictionary *)change 
        context:(void *)context 

에 알림을받을 테이블을 다시로드하고, 일단 relo 광고 테이블이 완료되면 YES가 완료되고 컨트롤이 connectionDidFinishLoading으로 돌아가고 올바르게 존재하면이 예외가 발생합니다.이 예외가 발생하는 코드 줄을 알지 못합니다.

흥미로운 점은 부울 플래그 dataSaved = YES를 설정하지 않으면 observeValueForKeyPath가 호출되지 않고 테이블이 다시로드되지 않는다는 것입니다.이 경우에는 예외가 발생하지 않습니다. 그것이 처음에는 테이블의 재 장전으로 인한 것이라고 생각하는 이유입니다. 실제로는 여전히 사실 일 수 있습니다.

내가 흐름

MyAppDelegate.m

if ([facebook isSessionValid]) { 
    locationHelper = [LocationHelper sharedInstance]; 
    tabBarController = [[AppTabBarController createTabBarController:self] retain]; 
    [self.window addSubview:tabBarController.view]; 
}else{ 
    loginPageController = [[LoginPageController alloc]initWithFacebook:facebook]; 
    loginNavigationController = [[UINavigationController alloc] initWithRootViewController:loginPageController]; 
    loginNavigationController.navigationBar.barStyle = UIBarStyleBlack; 
    loginPageController.navigationItem.hidesBackButton = YES; 
    [self.window addSubview:loginNavigationController.view]; 
    [loginPageController release]; 
    //[localNavigationController release]; 
} 

에게

+ (UITabBarController*) createTabBarController:(id)delegate { 
    UINavigationController *localNavigationController; 
    NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:2]; 


    FirstViewController *firstTabController = [[FirstViewController alloc]init]; 
    localNavigationController = [[UINavigationController alloc] 
     initWithRootViewController: firstTabController]; 
localNavigationController.navigationBar.barStyle = UIBarStyleBlack; 
    [localControllersArray addObject:localNavigationController]; 

    // release since we are done with this for now they are not part of the array 
    [localNavigationController release]; 
    [firstTabController release]; 

    FirstViewController *secondTabController = [[FirstViewController alloc]init]; 
localNavigationController = [[UINavigationController alloc]   
    initWithRootViewController: secondTabController]; 
    localNavigationController.navigationBar.barStyle = UIBarStyleBlack; 
    [localControllersArray addObject:localNavigationController]; 

// release since we are done with this for now they are not part of the array 
[localNavigationController release]; 
[secondTabController release]; 


UITabBarController* tabBarController = [[[UITabBarController alloc] init ] autorelease]; 

// load up our tab bar controller with the view controllers 
tabBarController.viewControllers = localControllersArray; 
tabBarController.delegate = delegate; 
// release the array because the tab bar controller now has it 
[localControllersArray release]; 
return tabBarController; 

}

LoginPageController.m

AppTabBarController.m을 설명하기 위해 내 코드의 일부를 걸었습니다
-(id)initWithFacebook:(Facebook*)facebookInstance{ 
self.facebook = facebookInstance; 
return self; 
    } 

    - (IBAction)fbButtonClick:(id)sender { 
NSArray *permissions; 
permissions = [NSArray arrayWithObjects: 
       @"email", nil]; 
[facebook authorize:permissions delegate:self]; 
    } 

- (void)fbDidLogin { 
NSLog(@"Inside LoginpageController fbDidLogin"); 
//NSLog(@"Access Token is %@", facebook.accessToken); 
//NSLog(@"Expiration Date is %@", facebook.expirationDate); 
// Store the value in the NSUserDefaults 
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    [defaults setObject:facebook.accessToken forKey:ACCESS_TOKEN_KEY]; 
    [defaults setObject:facebook.expirationDate forKey:EXPIRATION_DATE_KEY]; 
    [defaults synchronize]; 

// This is the best place to get user details because here we know that user has already logged in 
[facebook requestWithGraphPath:@"me" andDelegate:self]; 

}

- (void)request:(FBRequest *)request didLoad:(id)result { 
     NSLog(@"Inside LoginPageController didLoad"); 
     //NSLog(@"request returns user data %@",result); 
     MyAppDelegate* myAppDelegate = (MyAppDelegate*)[[UIApplication sharedApplication]delegate]; 
     [self.navigationController pushViewController:[AppTabBarController myAppDelegate] animated:YES]; 

    } 

LocationHelper.m //이 내가

[self.locationManager startUpdatingLocation]; 

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
//if the time interval returned from core location is more than two minutes we ignore it because it might be from an old session 
     [self.locationManager stopUpdatingLocation]; 
     self.currentLocation = newLocation; 
     [self updateDataBase]; 

} 

-(void)updateDataBase{ 
NSLog(@"Inside updateDataBase"); 
BackendHelper *backendHelper = [BackendHelper sharedInstance]; 
[backendHelper getData]; 

}

을 BackendHelper.m를 초기화 얻을

-(void) getData{ 

NSURL *getURL = [NSURL URLWithString: @"my url"]; 

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; 

//add our HTTP headers and URL 
[request setValue: @ "plain/text" forHTTPHeaderField : @"Content-Type"]; 
[request setHTTPMethod:@"GET"]; 
[request setURL : getURL]; 


// Use NSURLConnection to asynchronously download the data. This means the main thread will not 
// be blocked - the application will remain responsive to the user. 
// 
// IMPORTANT! The main thread of the application should never be blocked! 
// Also, avoid synchronous network access on any thread. 
// 

NSURLConnection* urlConnection = 
    [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease]; 

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
// check for HTTP status code for proxy authentication failures 
// anything in the 200 to 299 range is considered successful, 
// also make sure the MIMEType is correct: 
// 
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 
if ((([httpResponse statusCode]/100) == 2) && [[response MIMEType] isEqual:@"text/html"]) { 
    NSLog(@"Response status code is:%d", [httpResponse statusCode]); 
    self.responseData = [[NSMutableData alloc] init]; 
} else { 
    NSLog(@"didReceiveResponse error"); 
} 

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    NSLog(@"didReceiveData"); 
[responseData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
NSLog(@"didFailWithError"); 

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
NSLog(@"connectionDidFinishLoading"); 
[self handleResponseData:responseData]; 
[self.responseData release]; 
self.responseData = nil; 
} 



- (void) handleResponseData:(NSData*)data { 
NSString * strResult = [[NSString alloc] initWithData: data encoding:NSUTF8StringEncoding]; 
[[DatabaseHelper sharedInstance] saveData: strResult]; 
[strResult release]; 
} 

-(void) saveData:(NSString*) strResult{ 
// save data to the database 

dataSaved = YES; 

}

FirstViewController.m

- (void)viewDidLoad 
{ 
[databaseHelper addObserver:self forKeyPath:@"dataSaved" options:NSKeyValueObservingOptionNew context:nil]; 
uiTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 372) style:UITableViewStylePlain]; 
uiTableView.dataSource = self; 
uiTableView.delegate = self; 
uiTableView.separatorStyle = UITableViewCellSeparatorStyleNone; 
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"doot_background.png"]]; 
self.uiTableView.backgroundColor = background;//[UIColor blackColor]; 
uiTableView.scrollEnabled = NO; 
[background release]; 
[self.view addSubview:uiTableView]; 

} 

- (void)observeValueForKeyPath:(NSString *)keyPath 
        ofObject:(id)object 
        change:(NSDictionary *)change 
        context:(void *)context 
{ 
if([keyPath isEqualToString:@"dataSaved"]){ 

    DatabaseHelper *databaseHelperObject = (DatabaseHelper*)object; 
    if(databaseHelperObject.dootUpdated){ 
      //getData from the database 
      [self.uiTableView reloadData]; 
     } 
} 
} 
+0

추측하기 어렵습니다. 몇 가지 코드를 사용하십시오. –

+0

@Nick 여기에 어떤 코드를 써야할지 모르겠지만 네가 한 가지 잊어 버린 점은 헤더 용 customView를 가지고 있으며 사용자 정의 uitableviewcell을 가지고 있는데 어떤 코드가 도움이 될지 알려주므로 붙여 넣을 수 있습니다. 여기 – Yogesh

+0

많은 많은 시간 부호는 질문을 여기에서 해결하는 것을 도왔다. 최소한 스택 추적을 게시하십시오. 나는 이것에 대해 느낌을 가지고있다. –

답변

0

당신은 어떻게 우리를 표시해야 해당 사용자 지정보기를 만들 때.참고 : 해당 메서드가 viewForHeaderInSection이라고 할 때마다 항상 '새'사용자 지정보기를 만들어야하며, 반환 할 때 자동으로 렌더링하거나 [tableView reloadData]를 호출하기 전에 각 'header'에 대한 사용자 지정보기를 만들고 만든 다음 나중에 해제해야합니다. 이 오류는 사용자가 'autorelease'를 사용하여 customview를 반환 한 후 나중에 다시 사용하려고하기 때문에 발생합니다.

이 오류는 이미 해제 된 개체를 해제하려고하거나 해제 된 개체에 액세스하려고 할 때 일반적으로 발생합니다. 이제 해제 된 개체는 메모리의 다른 부분을 가리키는 포인터입니다.

  1. 당신이 좋아 '의 viewDidLoad'에서 사용자 정의보기를 만들 : 예를 들어,이이 문제를 야기

    MYVIEW = [[있는 CustomView의 ALLOC] initWithFrame ...] ....

    viewForHeaderInSection에서
  2. 이처럼 반환됩니다

    복귀 [MYVIEW 오토 릴리즈]

또는이 같은 :

viewDidLoad: 
myView = [[CustomView alloc] initWithFrame....]; 

.... 


cellForRow: 
cell.contentView = myView; 
[myView autorelease]; 

후 다시 viewForHeaderInSection 그것을 반환 : 반환 MYVIEW;

즉, 이는 할당 방식, 사용 방식 또는 자동 회수 방식과 관련이 있습니다. 완전한 viewController가 할당 해제 될 때 (또는 [tableView reloadData]를 호출 할 때) 또는 viewForHeaderInSection에 대한 각 호출에서 다음과 같이 새로운 사용자 정의보기를 만들 때이 뷰를 직접 생성하거나 해제해야합니다.

- (UIView*) viewForHeaderInSection: 
return [[[CustomView alloc] init] autorelease]; 
+0

그래, 내 코드를 확인하고이 모든게 괜찮은 것, 그리고 실제로 테이블이 제대로로드되고, 문제가 어딘가에, 혼란에 대한 죄송합니다 – Yogesh

0

필요한만큼 noOfSection을 반환 할 수 있습니다. 이 경우인지 확인하십시오. 얼마나 많은 섹션이 있는지 확인하십시오.

+0

@ Rahul이 문제를 조사해 주셔서 감사합니다, 나는 더 많은 정보를 추가했습니다 테이블이 제대로 다시로드되는 것처럼 보입니다. 문제는 다른 곳에서 발생합니다. – Yogesh

+0

@yogesh 소스를 보낼 수 있으면 문제를 조사 할 수 있습니다. –

+0

@Rahul, 더 많은 코드가 필요하면 여기에 코드를 추가했습니다. – Yogesh

관련 문제