최종 업데이트 :이 문제에 대한 수정 사항은 우울합니다. 프로젝트 내의 .xcodeproj 디렉토리로 이동하여 <username>.mode1v3
및 <username>.pbxuser
파일을 제거하십시오. 그것은 그것을 고쳤다. 부, Xcode.내 프로그램 objc_msgSend() 동안 _class_isInitialized() EXC_BAD_ACCESS받는 이유는 무엇입니까?
일반적인 유지/릴리스 버그가 아닙니다. 방금 내 코드의 개발 브랜치에서 시작되었지만, 버그는 마스터 브랜치에 존재하지 않으며, 응답에서 소스를 가리키는 차이점을 찾는 데 어려움을 겪고 있습니다. 그래서 나는 단지 피곤한 물건에 도착할 것이다.
보기 컨트롤러 클래스가 있습니다. 두 개의 다른 뷰 컨트롤러를 참조하는 두 개의 속성이 있습니다. 필요에 따라 각과 같이, 게터 접근을 통해로드 :
나중에 전화[self notesViewController]
에, 모든 좋은
- (NotesViewController *)notesViewController {
if (notesViewController == nil) {
notesViewController = [[NotesViewController alloc] initWithNibName:@"NotesViewController" bundle:nil];
}
return notesViewController;
}
. 하지만 아마도 그 전에 분명히 펜촉로드하는 동안, 그것을 밖으로 폭탄,
- (DateFieldController *)dateFieldController {
NSLog(@"made it into the method at least ...");
if (dateFieldController == nil) {
NSLog(@"nib loader, don't let us down...");
dateFieldController = [[DateFieldController alloc] initWithNibName:@"DateFieldController" bundle:nil];
}
return dateFieldController;
}
이 방법은 다른 접근과 같은 방식으로 호출되는 경우 :
2010-07-08 11:44:58.029 MyApp[24404:207] made it into the method at least ...
2010-07-08 11:44:58.030 MyApp[24404:207] nib loader, don't let us down...
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x028bb0ca in _class_isInitialized()
#1 0x028b9eca in _class_initialize()
#2 0x028bf1f6 in prepareForMethodLookup()
#3 0x028b86c9 in lookUpMethod()
#4 0x028b8836 in _class_lookupMethodAndLoadCache()
#5 0x028c6ad3 in objc_msgSend()
#6 0x00007bb3 in -[EntryViewController controllerForFieldType:] (self=0x7942d70, _cmd=0x190c20, type=0x79844b0) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/Classes/EntryViewController.m:481
#7 0x00007e07 in -[EntryViewController selectTypesControllerDidSelect:] (self=0x7942d70, _cmd=0x190bb4, type=0x79844b0) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/Classes/EntryViewController.m:527
#8 0x0000d2ad in -[TypesViewController tableView:didSelectRowAtIndexPath:] (self=0x5d2aac0, _cmd=0x1eac458, aTableView=0x6056000, indexPath=0x781c780) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/Classes/TypesViewController.m:81
#9 0x0059e718 in -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:]()
#10 0x00594ffe in -[UITableView _userSelectRowAtIndexPath:]()
#11 0x002abcea in __NSFireDelayedPerform()
#12 0x0274cd43 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__()
#13 0x0274e384 in __CFRunLoopDoTimer()
#14 0x026aad09 in __CFRunLoopRun()
#15 0x026aa280 in CFRunLoopRunSpecific()
#16 0x026aa1a1 in CFRunLoopRunInMode()
#17 0x02fd02c8 in GSEventRunModal()
#18 0x02fd038d in GSEventRun()
#19 0x0053ab58 in UIApplicationMain()
#20 0x00001e24 in main (argc=1, argv=0xbffff050) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/main.m:14
(gdb)
이 사람은, 그러나, 단지 작동이 중지
nib로드 메소드를 실행할 때 Simulator SDK에서 이상한 일이 발생하는 것으로 보입니다. 사실, 어쩌면 더 일찍. 오버 타고 DateFieldController
에 약간의 NSLog 액션으로 펜촉 로딩 초기화하는 것은 의심데도 우리를 얻을 수 없습니다 :
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
NSLog(@"come on, you...");
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
{
NSLog(@"rock on!");
}
return self;
}
충분 말을,이 NSLog 문 중 어느 것도 지금까지 실행됩니다.
무슨 일 이니? 왜 런타임이 나에게 날아 오르는거야? (self.dateFieldController
에서 [self dateFieldController]
으로 전화를 전환해도 버그가 수정되지 않으며,이 코드는 충돌이없는 마스터 분기의 코드와 정확히 동일 함을 기억하십시오.
FWIW, 시뮬레이터 4.0, 디버그, i386 아치 (OS X 10.6.3을 실행하는 새로운 Mac Book Pro)에서 컴파일하는 Xcode 3.2.3 64 비트를 사용하여 구축 중이며 프로젝트 설정의 배포 대상이 설정됩니다. "iPhone OS 3.0"(uppping to this 3.1.3) 역시이 문제를 해결하지 못합니다. 요청에 따라는 controllerForFieldType:
의 구현 :
는 업데이트 나는 그것이 특히 관련이 있다고 생각하지 않기 때문에 나는 초를 남겨
- (id)controllerForFieldType:(Type *)type {
id controller = nil;
if ([type.mode isEqualToString:@"note"]) {
controller = self.notesViewController;
} else if ([type.mode isEqualToString:@"date"]) {
NSLog(@"going for it, attempting to load dateFieldController from accessor...");
controller = self.dateFieldController;
} else {
controller = self.fieldViewController;
}
return controller;
}
는 문제에서, 스택 이후에 일어나고있는 것 같다 실제의 getter 메소드 dateFieldController
업데이트 II : @ zneak의 제안에 따라 Run -> Enable Guard Malloc 설정을 사용하고 시나리오를 다시 실행했습니다. 결과는 기본적으로 동일하지만 런타임의 내부 백 트레이스가 다릅니다. 무언가가 디코딩되는 것을 방지 년대 클래스 또는 NIB 잘못 것으로 생각된다 :
2010-07-08 12:26:26.180 Strip[24961:207] made it into the method at least ...
2010-07-08 12:26:26.289 Strip[24961:207] nib loader, don't let us down...
Program received signal: “EXC_BAD_ACCESS”.
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.)
(gdb) bt
#0 0x028cd41f in attachMethodLists()
#1 0x028cdf77 in realizeClass()
#2 0x028cedad in _class_getNonMetaClass()
#3 0x028c8eb0 in _class_initialize()
#4 0x028ce1f6 in prepareForMethodLookup()
#5 0x028c76c9 in lookUpMethod()
#6 0x028c7836 in _class_lookupMethodAndLoadCache()
#7 0x028d5ad3 in objc_msgSend()
#8 0x00007b81 in -[EntryViewController controllerForFieldType:] (self=0x38cfaf30, _cmd=0x190c8f, type=0x3cacbfe0) at /Users/wgray/Documents/Sources/iPhone/strip-iphone/Classes/EntryViewController.m:482
...snip...
#22 0x00001de4 in main (argc=1, argv=0xbfffefec) at /Users/wgray/Documents/Sources/iPhone/strip-iphone/main.m:14
(gdb)
업데이트 III를 : 음모가 두껍게하는.의견에서 @ ohorob의 제안에 따라 env arg OBJC_PRINT_INITIALIZE_METHODS = YES를 추가하여 여기에있는 하나의 클래스를 제외한 앱의 모든 단일 클래스 초기화가 잘 보이는 것으로 나타났습니다. 나는 응용 프로그램을 실행하고 폭발에 이르게 테이블 행을 선택하면
objc[26750]: INITIALIZE: calling +[UIPinchGestureRecognizer initialize]
objc[26750]: INITIALIZE: finished +[UIPinchGestureRecognizer initialize]
objc[26750]: INITIALIZE: UIPinchGestureRecognizer is fully +initialized
, 우리는 단지 충돌하기 전에 nslog 콘솔 출력을보고, 충돌 자체 : 각 콘솔 출력이 같은 대한 보인다. 나는 이것이 부적절한 초기화를 배제 할 수 있다는 것을 의미한다고 생각하고 싶다. 그러나 나는 런타임에 대한 전문가가 아니다.
master 브랜치와이 dev 브랜치 간의 코드 차이에 대한 철저한 감사를했는데, 아직 포인터를 밟았 음을 나타내는 아무것도 발견되지 않았지만, 나는 그것이 대부분 계속 될 것이라고 생각하고 있습니다.
또한 [[EntryViewController controllerForFieldType :]'의 코드를 게시하십시오 ... –
우리는 위에서 보았던 로그 메시지를 고려할 때 아마도 무의미하다고 생각합니다. –
'dateFieldController'가 스택 추적에 나타나지 않고 코드가 작동중인 버전에서 변경되지 않았다면 문제가 실제로 다른 곳인지 의심 할 수 없습니다. 예 :'controllerForFieldType'은 어떻게 생겼습니까? – walkytalky