2011-08-22 27 views
21

Uygulama içi satın alımım için bir test çalıştırma (ilk kez uygulama satın alımlarında). Ben bu kodun üçüncü satırda EXC_BAD_ACCESS olsun:EXC_BAD_ACCESS, uygulama satın alma testi sırasında

SKPayment *payment = [SKPayment paymentWithProduct:electronicProd]; 
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    [[SKPaymentQueue defaultQueue] addPayment:payment]; 

if bir düğme için bir IBAction altındadır. electronicPack, SKProduct olarak başlıkta bildirildi. ProductsRequest didReceiveResponse ürünündeki bazı NSLog'ları attı ve ürün istendiğinde (viewDidLoad'da) ve ürünü doğru bir şekilde aldığını ve elektronikPack'de sakladığını gösterdi. DidReceiveResponse sayfasında [[request.products] objectAtIndex: 0] olarak tanımlı electronicPack. Evet evet. Im, nerede ne yapacağını bilmiyorum. Herhangi bir yardım takdir edilir.

GÜNCELLEME: yanlışlıkla fazladan işlem gözlemci lol Sen bir sallanmasını havuzda sistem tarafından sarılır

- (void)viewDidLoad { 
    //... stuff 
    SKProduct* electronicProduct = //... 
    [electronicProduct retain]; 
    //... otherstuff 
} 

viewDidLoad oluştururken nesneyi tutmak gerekir

+0

:

Burada AppDelegate içinde bir örnek, bu fark önce hata var? Her olay bir otomatikleştirme havuzuna sarılır, eğer nesneyi statik init yöntemiyle başlatırsanız, viewDidLoad yöntemi bittikten sonra öğe serbest bırakılır. – andreamazz

+0

Eğer ben yaptım mı soruyorsun: electronicPack = [SKProduct ayırma] init] ? Bunun cevabı hayır. Eğer senin istediğin şey değilse, o zaman ne dediğinden emin değilim, bu ballgame için biraz yeni. lol –

+0

Tüm bellek yönetimi, özellik şeyler ile çok iyi değilim. ve tüm bunlar. Sadece bir ay kadar süredir programlama yapıyordum ve henüz bu kadar başarılı olamamışlar. Bunu bir deneyin ve bir şey düzeltip düzeltmediğini sorun. DÜZENLEME: self.elec..etc öğelerini uyguladı ve değiştirilmedi. uygulama çöktüğünde hala hata alıyorum –

cevap

9

ekleyerek oldu kodunda sol SABİT , paymentWithProduct: bir autorelease nesnesini döndürür. ViewDidLoad bittiğinde, tüm autorelease nesneleri serbest bırakılır, bu yüzden daha sonra erişmeye çalıştığınızda kötü bir bellek erişimi elde edersiniz.

39

Ben aynı sorunu yaşadım, benim çözüm Benim App In-App Store'u ayrılırken

[[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 

aramak oldu. Belki gelecekte birine yardımcı olacaktır.

+1

Günümü kurtardın! Teşekkürler! –

+0

Ohhoo .. Harika .. Teşekkürler –

+0

Benim için de çalıştım, teşekkürler! – JustMe

26

Sorun, bir öncekini kaldırmadan önce bir işlem gözlemcisi eklemeye çalışmaktan kaynaklanıyor gibi görünüyor. Bu sorunu gidermek için aşağıdaki adımları denetleyicinize ekleyin:

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 
} 

Bu yardımcı olur umarız!

+1

Bu benim için cevaptı. Xcode 6.3 ve iOS 8.3 – Paul

+2

ile hala geçerlidir Mükemmel, teşekkürler! Benim için bu, aynı zamanda, Mihael Isaev'in (aşağıda) kodunu kullanarak ve ViewDidDisappear'a yerleştirerek çalıştı. – Pieter

2

Aynı hatayı, gerçekten çözmek için oldukça basit vardı.

@property SKProduct *product; 

Sadece olarak değiştirdim: Benim üstbilgi dosyasında bir SKProduct ilan vardı

@property (retain) SKProduct *product; 

ve tüm iyi çalışıyor. Umut, bu birisine yardımcı olur.

+0

benim sorunumu çözüyor gibi görünüyor. – NSGodMode

11

Mr.T cevap en iyi çözüm! Burada bu removeTransactionObserver diyoruz Swift ise

: Ben aynı sorunu var

deinit { 
    SKPaymentQueue.defaultQueue().removeTransactionObserver(self) 
} 
+0

Deinit nerede yapıyorsunuz? appdelegate dosyası !? – Learn2Code

0

, benim çözüm [removeTransactionObserver [SKPaymentQueue defaultQueue]: kendinden] aramaya vardı; mağaza gözlemci işlem bitiş/başarısız/tamamlanan geri aramaları

1

bunu muhafaza edilmesi gerektiğini unutmayın SKPaymentTransactionObserver için özel bir sınıf oluşturuyorsanız üzerinde

.Mesajı korumak dedin, electronicProd tanımda

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 
    } 

    // ... 
} 
İlgili konular