Ответ 1
Посмотрите NSZombieEnabled, он сделает все, что будет освобождено в объект, который будет регистрировать сообщение, когда и кто его вызвал. Это очень полезно для отслеживания этих типов проблем EXC_BAD_ACCESS.
У меня есть UITableView
с разными покупками приложений. Каждый параметр выведет вас на контроллер просмотра, у которого также есть делегат, и что не делать в покупках приложений. Файл plist изменяется, чтобы определить, какая опция в представлении таблицы была выбрана. Все это прекрасно работает. Я поставил NSLogs, чтобы убедиться, что переменная была установлена. Однако, когда я нажимаю кнопку "покупать", она работает только половину времени, а другая половина я получаю
EXC_BAD_ACCESS
в строке:
[[SKPaymentQueue defaultQueue] addPayment:payment];
Все настроено правильно, поскольку покупки в приложении идут, потому что он работал прежде, чем я переключился на этот способ выполнения. Я думаю, что это может иметь какое-то отношение к вызову productsRequest, потому что я настроил NSLog
в делегате didReceiveResponse
, и он получил ответ намного быстрее после первого раза. Я застрял. Те, которые не работают, всегда случайны, не рифмы или причины. Любая помощь приветствуется.
Посмотрите NSZombieEnabled, он сделает все, что будет освобождено в объект, который будет регистрировать сообщение, когда и кто его вызвал. Это очень полезно для отслеживания этих типов проблем EXC_BAD_ACCESS.
У меня возникла эта проблема и я обнаружил, что проблема заключается в том, что я освобождаю наблюдателя транзакций, который я добавил к стандартным SKPaymentQueue. По-видимому, SKPaymentQueue не сохраняет своих наблюдателей, вероятно, для предотвращения цикла удержания.
Итак, в частности, я изменил этот код:
- (void) setupAppStoreObserver {
AppStoreObserver *appStoreObserver = [[AppStoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:appStoreObserver];
[appStoreObserver release]; // This is the problem
}
Для этого:
- (void) setupAppStoreObserver {
AppStoreObserver *appStoreObserver = [[AppStoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:appStoreObserver];
// Note, we don't release the appStoreObserver because it is not
// actually retained by SKPaymentQueue (probably to prevent retain cycles)
}
Вам нужно удалить наблюдателя:
- (void)viewDidDisappear:(BOOL)animated {
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
MyStoreObserver * observer = [[MyStoreObserver alloc] init];
объект наблюдателя ушел после вызова. создать переменную-член для хранения MyStoreObserver может быть исправлением.
У меня были те же симптомы: EXC_BAD_ACCESS на addPayment мое решение было другим... и, в конце концов, легким.
Чтение учебника Ray Wenderlichs, где он обсуждает ошибку EXC_BAD_ACCESS, см. это, говорит он, вы получаете эту ошибку, когда пытаетесь получить доступ к объекту, который был освобожден.
Я инициализировал MyStoreObserver, где ViewController загрузил. Я переместил это в initWithNibName... вы знаете, прямо под тем, где был набран шаблон // Пользовательская инициализация идет здесь. Код, который я там поставил, был
MyStoreObserver *observer = [[MyStoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];