在 App Purchase 中导致偶尔崩溃

In App Purchase causes occasional crash

我在互联网上搜索了这方面的帮助,但无济于事。我的应用程序在应用程序商店上线,少数用户报告应用程序冻结并在进行应用程序内购买后崩溃(我游戏中唯一的 IAP,它基本上解锁了完整版本)。即使他们重新启动设备并尝试继续,它也会再次崩溃。我无法重现崩溃 - 这是崩溃报告:

{"bug_type":"109","os_version":"iPhone OS 9.2 (13C75)","timestamp":"2015-12-12 15:34:59.59 +0000","build_version":"1","app_name":"MyApp","bundleID":"com.MyName.MyApp","name":"MyApp","is_first_party":false,"app_version":"1.0","share_with_app_devs":true,"slice_uuid":"7abb6a6c-91be-3da0-af0f-2cc21f9a6b83","adam_id":1021569826}
Incident Identifier: 59B078E3-ABC9-47C7-A3BE-6311BBB968F6
CrashReporter Key:   b30d57098eecd5a7dfcd44f3a04cfb01bdef557f
Hardware Model:      iPad2,5
Process:             MyApp [977]
Path:                /private/var/mobile/Containers/Bundle/Application/EFAB47F6-F1A3-42A4-A6F1-8A038932ED86/MyApp.app/MyApp
Identifier:          com.MyName.MyApp
Version:             1 (1.0)
Code Type:           ARM (Native)
Parent Process:      launchd [1]

Date/Time:           2015-12-12 15:34:59.59 +0000
Launch Time:         2015-12-12 15:30:02.02 +0000
OS Version:          iOS 9.2 (13C75)
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000000e7ffdefe
Triggered by Thread:  0

Filtered syslog:
None found

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   MyApp                       0x001f8cb8 function signature specialization <Arg[0] = Dead and Owned To Guaranteed, Arg[1] = Owned To Guaranteed> of MyApp.IAPHelper.paymentQueue (MyApp.IAPHelper)(__ObjC.SKPaymentQueue, updatedTransactions : [__ObjC.SKPaymentTransaction]) -> () (IAPHelper.swift:0)
1   MyApp                       0x001f59a8 @objc MyApp.IAPHelper.paymentQueue (MyApp.IAPHelper)(__ObjC.SKPaymentQueue, updatedTransactions : [__ObjC.SKPaymentTransaction]) -> () (IAPHelper.swift:0)
2   StoreKit                        0x2e7c1a80 __NotifyObserverAboutChanges + 82
3   CoreFoundation                  0x25464630 CFArrayApplyFunction + 34
4   StoreKit                        0x2e7c1a1c -[SKPaymentQueue _notifyObserversAboutChanges:sendUpdatedDownloads:] + 126
5   StoreKit                        0x2e7c2318 -[SKPaymentQueue _processUpdates:trimUnmatched:sendUpdatedDownloads:] + 1042
6   StoreKit                        0x2e7c2ca6 -[SKPaymentQueue _updatePaymentsForMessage:] + 120
7   StoreKit                        0x2e7c1938 __44-[SKPaymentQueue _handleMessage:connection:]_block_invoke + 142
8   libdispatch.dylib               0x250c9b5a _dispatch_call_block_and_release + 8
9   libdispatch.dylib               0x250c9b46 _dispatch_client_callout + 20
10  libdispatch.dylib               0x250d7ee0 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1522
11  CoreFoundation                  0x255133fc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 6
12  CoreFoundation                  0x255118f6 __CFRunLoopRun + 1572
13  CoreFoundation                  0x25464bf8 CFRunLoopRunSpecific + 518
14  CoreFoundation                  0x254649e4 CFRunLoopRunInMode + 106
15  GraphicsServices                0x266b0ac8 GSEventRunModal + 158
16  UIKit                           0x296f4ba0 UIApplicationMain + 142
17  MyApp                       0x0018bc24 main (AppDelegate.swift:12)
18  libdyld.dylib                   0x25113872 start + 0

Thread 1 name:  Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0   libsystem_kernel.dylib          0x251e6320 kevent_qos + 24
1   libdispatch.dylib               0x250de098 _dispatch_mgr_invoke + 254
2   libdispatch.dylib               0x250dddf6 _dispatch_mgr_thread$VARIANT$mp + 36

Thread 2 name:  com.apple.NSURLConnectionLoader
Thread 2:
0   libsystem_kernel.dylib          0x251d0c24 mach_msg_trap + 20
1   libsystem_kernel.dylib          0x251d0a28 mach_msg + 38
2   CoreFoundation                  0x25513354 __CFRunLoopServiceMachPort + 134
3   CoreFoundation                  0x255116dc __CFRunLoopRun + 1034
4   CoreFoundation                  0x25464bf8 CFRunLoopRunSpecific + 518
5   CoreFoundation                  0x254649e4 CFRunLoopRunInMode + 106
6   CFNetwork                       0x25aa781e +[NSURLConnection(Loader) _resourceLoadLoop:] + 484
7   Foundation                      0x25d69164 __NSThread__start__ + 1146
8   libsystem_pthread.dylib         0x2528985a _pthread_body + 136
9   libsystem_pthread.dylib         0x252897ce _pthread_start + 108
10  libsystem_pthread.dylib         0x25287724 thread_start + 6

Thread 3 name:  com.apple.CFSocket.private
Thread 3:
0   libsystem_kernel.dylib          0x251e4f14 __select + 20
1   CoreFoundation                  0x255187a2 __CFSocketManager + 564
2   libsystem_pthread.dylib         0x2528985a _pthread_body + 136
3   libsystem_pthread.dylib         0x252897ce _pthread_start + 108
4   libsystem_pthread.dylib         0x25287724 thread_start + 6

Thread 4:
0   libsystem_kernel.dylib          0x251e588c __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x25287b34 _pthread_wqthread + 1034
2   libsystem_pthread.dylib         0x25287718 start_wqthread + 6

Thread 5:
0   libsystem_kernel.dylib          0x251e588c __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x25287b34 _pthread_wqthread + 1034
2   libsystem_pthread.dylib         0x25287718 start_wqthread + 6

Thread 6:
0   libsystem_kernel.dylib          0x251e588c __workq_kernreturn + 8
1   libsystem_pthread.dylib         0x25287b34 _pthread_wqthread + 1034
2   libsystem_pthread.dylib         0x25287718 start_wqthread + 6

Thread 0 crashed with ARM Thread State (32-bit):
r0: 0x00000000    r1: 0x3bc6d0b0      r2: 0x00000000      r3: 0x00000000
r4: 0x00000000    r5: 0x17222bc2      r6: 0x15ea4330      r7: 0x003fdaf0
r8: 0x1736bce0    r9: 0x00000000     r10: 0x003fdbcc     r11: 0xffffffff
ip: 0xf6535949    sp: 0x003fd934      lr: 0x001f7478      pc: 0x001f8cb8
cpsr: 0x60000010

Binary Images:
<not included for reasons of brevity>

引用的导致崩溃的方法如下:

public func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
 for transaction in transactions {
  switch (transaction.transactionState) {
  case .Purchased:
    completeTransaction(transaction)
    break
  case .Failed:
    failedTransaction(transaction)
    break
  case .Restored:
    restoreTransaction(transaction)
    break
  case .Deferred:
    break
  case .Purchasing:
    break
  }
 }
}

我不确定从哪里开始真正开始,因为 paymentQueue: updatedTransactions 中的代码对我来说看起来不错,实际上是直接取自 Ray Wenderlich 关于 IAP 的教程:http://www.raywenderlich.com/105365/in-app-purchases-tutorial-getting-started

这让我特别困惑: function signature specialization <Arg[0] = Dead and Owned To Guaranteed, Arg[1] = Owned To Guaranteed>这是什么意思?

有人有什么想法吗?或者关于如何重现崩溃的建议?因为它只发生过几次,这可能与用户的设备或 Apple 的 IAP 处理有关,还是绝对是我的代码?

提前致谢!

编辑:

为了回应 Alpesh 的回答,我的函数现在看起来像这样:

public func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
  let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
  dispatch_after(delayTime, dispatch_get_main_queue()) {

    for transaction in transactions {
      switch (transaction.transactionState) {
      case .Purchased:
        self.completeTransaction(transaction)
        break
      case .Failed:
        self.failedTransaction(transaction)
        break
      case .Restored:
        self.restoreTransaction(transaction)
        break
      case .Deferred:
        break
      case .Purchasing:
        break
      }
    }
  }
}

这是由于内存问题导致的崩溃。我认为你在延迟一段时间后输入这样的代码,它可以正常工作。你也可以使用 GCD Dispatch Timer

public func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
                dispatch_after(delayTime, dispatch_get_main_queue()) {

                for transaction in transactions {
  switch (transaction.transactionState) {
  case .Purchased:
    completeTransaction(transaction)
    break
  case .Failed:
    failedTransaction(transaction)
    break
  case .Restored:
    restoreTransaction(transaction)
    break
  case .Deferred:
    break
  case .Purchasing:
    break
  }
 }

} }