EXC_BAD_ACCESS во время тестирования покупки приложения
Запуск теста для покупки в приложении (первое время в покупках приложений). Я получаю EXC_BAD_ACCESS в третьей строке этого кода:
SKPayment *payment = [SKPayment paymentWithProduct:electronicProd];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
Под кнопкой IBAction находится кнопка. electronicPack объявляется в заголовке как SKProduct. Бросил некоторые NSLogs в productRequest didReceiveResponse, и когда продукт был запрошен (в viewDidLoad), и они показали, что он правильно извлекает продукт и хранит его в электронном пакете. Определенный электронный пакет как [[request.products] objectAtIndex: 0] на странице didReceiveResponse. Так что да. Thats где im at, не знаю, что делать. Любая помощь приветствуется.
UPDATE: FIXED случайно оставлен в коде, добавляющем дополнительный наблюдатель транзакций lol
Ответы
Ответ 1
Вам нужно сохранить создаваемый объект
- (void)viewDidLoad {
//... stuff
SKProduct* electronicProduct = //...
[electronicProduct retain];
//... otherstuff
}
viewDidLoad завершается системой в пуле автозаполнения, paymentWithProduct: возвращает объект авторекламы. Когда viewDidLoad завершен, все объекты автозапуска освобождаются, поэтому вы получаете плохой доступ к памяти, когда пытаетесь получить к нему доступ позже.
Ответ 2
У меня была такая же проблема, мое решение состояло в том, чтобы позвонить
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
при выходе из In-App Store в моем приложении.
Возможно, это поможет кому-то в будущем.
Ответ 3
Похоже, проблема заключается в попытке добавить наблюдателя транзакций перед удалением предыдущего. Добавьте к контроллеру следующее, чтобы устранить эту проблему:
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
Надеюсь, это поможет!
Ответ 4
Ответ Mr.T - лучшее решение!
В swift я вызываю этот removeTransactionObserver здесь:
deinit {
SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
}
Ответ 5
У меня была такая же ошибка, довольно просто решить на самом деле. В моем заголовочном файле у меня был объявлен SKProduct:
@property SKProduct *product;
Я просто изменил его на:
@property (retain) SKProduct *product;
и все работает отлично.
Надеюсь, это поможет кому-то.
Ответ 6
У меня такая же проблема, мое решение заключалось в том, чтобы позвонить
[[SKPaymentQueue defaultQueue] removeTransactionObserver: self];
по завершению транзакции сохранения наблюдателя/неудачных/завершенных обратных вызовов
Ответ 7
Если вы создаете выделенный класс для SKPaymentTransactionObserver
, не забывайте, что он должен быть сохранен.
Я получил ошибку, прежде чем осознать это, здесь пример в AppDelegate
:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var myTransactionObserver: MyTransactionObserver!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// don't
let myTransactionObserver = MyTransactionObserver()
// do
myTransactionObserver = MyTransactionObserver()
SKPaymentQueue.default().add(myTransactionObserver)
return true
}
// ...
}