2011-08-22 64 views
21

爲我的應用程序購買(第一次在應用程序購買時)運行測試。我得到這個代碼的第三行EXC_BAD_ACCESS:EXC_BAD_ACCESS在應用程序購買測試期間

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

的是一個按鈕的IBAction爲下。 electronicPack在標題中聲明爲SKProduct。在productsRequest didReceiveResponse中引入了一些NSLog,並且在產品被請求時(在viewDidLoad中),他們表明它正確地獲取產品並將其存儲在electronicPack中。在didReceiveResponse頁面中將定義的electronicPack定義爲[[request.products] objectAtIndex:0]。所以是的。那就在那裏,不知道該怎麼做。任何幫助表示讚賞。

更新:修正意外地留在了增加額外的交易觀察者笑

+0

在electronicProd定義,你叫保留的消息?每個事件都被包裹在一個自動釋放池,如果您的實例化對象與它的靜態init方法,該項目將被髮布一次viewDidLoad方法結束。 – andreamazz

+0

你要問,如果我不喜歡: electronicPack = [SKProduct的alloc]初始化] ?答案是否定的。如果那不是你要求的那麼我不知道你在說什麼,我有點新的這個球賽。大聲笑 –

+0

我不太好整個內存管理,財產的東西。和所有這一切。只有約一個月的編程,並沒有完全採取這一點呢。我給一個嘗試壽,看看是否能解決什麼 編輯:實現的self.elec..etc的東西,並沒有變化。當應用程序崩潰時仍然出現錯誤 –

回答

9

您需要保留正在創建

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

viewDidLoad中由系統在自動釋放池包裹目標代碼,paymentWithProduct:返回一個autorelease對象。當viewDidLoad完成時,所有的autorelease對象都被釋放,這就是爲什麼當你稍後嘗試訪問它時,你會遇到不好的內存訪問。

39

我有同樣的問題,我的解決辦法是要求

[[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 

在離開的In-App Store裏我的應用程序。 也許它將在未來幫助某人。

+1

你救了我的一天!謝謝! –

+0

Ohhoo ..大..感謝 –

+0

爲我工作爲好,謝謝! – JustMe

26

似乎這個問題是在刪除前一個事件之前嘗試添加一個事務觀察者。以下添加到您的控制器來解決這個問題:

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

希望這有助於!

+1

這是我的答案。仍然適用於Xcode 6.3和iOS 8.3 – Paul

+2

非常好,謝謝!對我來說,這也工作,使用來自Mihael Isaev(下面)的代碼並將其放入ViewDidDisappear中。 – Pieter

2

我有同樣的錯誤,真的很容易解決。在我的頭文件我有一個SKProduct聲明:

@property SKProduct *product; 

我只是把它改爲:

@property (retain) SKProduct *product; 

,這一切工作正常。 希望這可以幫助別人。

+0

似乎解決了我的問題。 – NSGodMode

11

Mr.T答案是最好的解決方案!

在SWIFT我把這個removeTransactionObserver這裏:

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

你在哪裏做deinit!? appdelegate文件!? – Learn2Code

0

我有同樣的問題,我的解決辦法是要求 [SKPaymentQueue defaultQueue] removeTransactionObserver:自我]。

在商店觀察者交易完成/失敗/完成回調

1

如果您正在爲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 
    } 

    // ... 
}