Во-первых, заранее спасибо, что нашли время, чтобы прочитать это. Я искал ответ на этот вопрос в течение нескольких дней, но я не могу найти то, что я ищу. Я знаю, что ошибки SIGSEGV (или ошибки EXEC_BAD_ACCESS) обычно вызваны проблемами управления памятью, но после нескольких часов просмотра кода я не могу найти ошибку. Статический анализатор тоже ничего не нашел.
Как видно из заголовка, эта ошибка возникает только на устройстве (никогда в симуляторе) и не происходит каждый раз при загрузке данного представления. Очевидно, это означает, что я не могу использовать NSZombie для отладки того, что идет не так.
Начнем с журнала аварийного дампа:
0 myApp 0x00036659 +[TFCrashHandler backtrace] + 428
1 myApp 0x00036a6f TFSignalHandler + 54
2 libsystem_c.dylib 0x32f48539 _sigtramp + 48
3 UIKit 0x365701df -[UIView(Rendering) setNeedsDisplay] + 86
4 UIKit 0x36598269 -[UILabel setFont:] + 232
5 myApp 0x000190eb +[BruUISettings applyLabelDetailStyle:] (BruUISettings.m:130)
6 myApp 0x0001aa57 -[ActiveChallengeViewController viewDidLoad] (ActiveChallengeViewController.m:115)
7 UIKit 0x365a57ff -[UIViewController view] + 166
8 UIKit 0x365b1c39 -[UIViewController contentScrollView] + 24
9 UIKit 0x365b1aa9 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 36
10 UIKit 0x365b198f -[UINavigationController _layoutViewController:] + 34
11 UIKit 0x365b115b -[UINavigationController _startTransition:fromViewController:toViewController:] + 318
12 UIKit 0x365b0f53 -[UINavigationController _startDeferredTransitionIfNeeded] + 250
13 UIKit 0x365a5673 -[UINavigationController pushViewController:transition:forceImmediate:] + 806
14 UIKit 0x365a5349 -[UINavigationController pushViewController:animated:] + 36
15 myApp 0x00015dc7 -[ChallengesHomeViewController tableView:didSelectRowAtIndexPath:] (ChallengesHomeViewController.m:325)
16 UIKit 0x3661f565 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 944
17 UIKit 0x36697ce7 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 158
18 Foundation 0x31f7a943 __NSFireDelayedPerform + 414
19 CoreFoundation 0x34ab1a63 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
20 CoreFoundation 0x34ab16c9 __CFRunLoopDoTimer + 364
21 CoreFoundation 0x34ab029f __CFRunLoopRun + 1206
22 CoreFoundation 0x34a334dd CFRunLoopRunSpecific + 300
23 CoreFoundation 0x34a333a5 CFRunLoopRunInMode + 104
24 GraphicsServices 0x351a7fed GSEventRunModal + 156
25 UIKit 0x3659a743 UIApplicationMain + 1090
26 myApp 0x000026c5 main (main.m:13)
27 myApp 0x0000265c start + 52
Обратите внимание, я использую TestFlight с testflightapp.com, и там есть обработчик исключений в верхней части стека.
Вот код, который создает и передает рассматриваемый контроллер представления:
CDAcceptedChallenge *challengeAtIndex = [self.activeChallenges objectAtIndex:[indexPath row]];
ActiveChallengeViewController *view = [[ActiveChallengeViewController alloc] initWithNibName:@"ActiveChallengeViewController"
bundle:nil
activeChallenge:challengeAtIndex];
view.leaveChallengeTarget = self;
[self.navigationController pushViewController:view animated:YES];
[view release];
Этот код выполняется внутри метода didSelectRowAtIndex, если это вообще имеет значение. Этот контроллер представления имеет несколько переменных-членов и IBOutlets, которые ссылаются на объекты в кончике, но вот те, которые соответствуют объекту, упомянутому в этой ошибке:
в .ч:
UILabel *helpLabel;
...
@property (nonatomic, retain) IBOutlet UILabel *helpLabel;
в .м:
@synthesize helpLabel;
Я уверен, что helpLabel привязан к правильному объекту в кончике, потому что он получает правильное оформление, когда это не взрывается. Далее приведен метод init для этого контроллера представления:
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.activeChallenge = inActiveChallenge;
}
return self;
Вот метод viewDidLoad, где мы иногда будем видеть сбой (выделен жирным шрифтом). Обратите внимание, что здесь много чего происходит, но ничто не затрагивает self.helpLabel, что в конечном итоге вызывает сбой.
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:FALSE];
self.navigationItem.title = @"Details";
// overlay disclosure creation
self.overlayDisclosure = [CustomColoredDisclosureIndicator accessoryWithColor:self.challengeNameLabel.textColor];
self.overlayDisclosure.highlightedColor = [UIColor whiteColor];
[self.overlayDisclosure addTarget:self action:@selector(overlayViewButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.overlayDisclosure];
[[BruNotificationManager instance] registerForTabUpdated:[[[BruCallback alloc] initWithTarget:self
andCallback:@selector(tabUpdated:)] autorelease]];
[[BruNotificationManager instance] registerForActiveChallengesUpdated:[BruCallback buildFromObject:self
andCallback:@selector(challengesUpdatedLocally)]];
[[BruNotificationManager instance] registerForEarnedRewardsUpdated:[BruCallback buildFromObject:self
andCallback:@selector(rewardsUpdatedLocally:)]];
[super refreshEarnedRewardsForChallenge:self.activeChallenge.challenge.identifier];
[super refreshTabForChallenge:self.activeChallenge.challenge.identifier];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:@selector(addBeer)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
// Request that the object download its image
BruCallback *imageCallback = [BruCallback buildFromObject:self andCallback:@selector(imageRequestCompleted:withData:)];
self.challengeImageView.image = [self.activeChallenge.challenge retrieveImage:self.bruConnection withCallback:imageCallback];
// Create our help label
**[BruUISettings applyLabelDetailStyle:self.helpLabel];**
self.helpLabel.textColor = AccentSecondaryColor;
self.overlayView.alpha = [BruUISettings standardOverlayViewAlpha];
[BruUISettings applyTableStyle:self.rewardsTable];
[BruUISettings applyScrollViewStyle:self.scrollView];
self.needToUpdateTab = YES;
self.needToUpdateRewards = YES;
self.needToUpdateChallenge = NO;
Вот урезанная версия метода viewDidUnload, хотя я не понимаю, почему это будет иметь значение в этом случае:
...
self.helpLabel = nil;
...
[super viewDidUnload];
Наконец, мой [BruUISettings applyLabelDetailStyle] - это метод, который применяет централизованный стиль к моей метке. В моем коде есть несколько мест, где эта функция используется, так что я могу изменить все стили для этих меток, просто изменив одну функцию.
+ (void) applyLabelDetailStyle:(UILabel *)inLabel
{
inLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:12.0];
inLabel.textColor = [UIColor darkGrayColor];
inLabel.backgroundColor = [UIColor clearColor];
}
Будем весьма благодарны за любые мысли о том, что здесь может происходить. Еще раз спасибо.