ios - 观察者是否被 Swift 单例永久保留?

标签 ios swift storekit

我的应用支持应用内购买和自动续订订阅,因此每当系统发布续订通知时,SKPaymentTransactionObserver 都会得到适当的通知,这一点很重要。

我更喜欢将我的 StoreKit 代码与 AppDelegate 分开,所以我为它创建了一个单例,并在 AppDelegate 中引用。

class AppDelegate: UIResponder, UIApplicationDelegate {

    let storeKitManager = DFStoreKitManager.shared

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

        storeKitManager.register()

        //...

        return true
    }

    func applicationWillTerminate(_ application: UIApplication) {

        storeKitManager.deregister()
    }

}

我将共享实例添加为 SKPaymentQueue 的观察者。

class DFStoreKitManager: NSObject {

    static let shared = DFStoreKitManager()
    private override init() { //This prevents other classes from using the default '()' initializer for this class.
        super.init()
    }

    func register() {
        SKPaymentQueue.default().add(self)
    }

    func deregister() {
        SKPaymentQueue.default().remove(self)
    }

    //...
}

extension DFStoreKitManager: SKPaymentTransactionObserver {

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for tx in transactions {

            switch tx.transactionState {
            case .purchasing:   print("SKPaymentTransaction purchasing")
            case .deferred:     print("SKPaymentTransaction deferred")
            case .failed:       print("SKPaymentTransaction failed")

                //...
                queue.finishTransaction(tx)

            case .restored:     print("SKPaymentTransaction restored")

                //...
                queue.finishTransaction(tx)

            case .purchased:    print("SKPaymentTransaction purchased")

                //...
                queue.finishTransaction(tx)
            }
        }
    }

    func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
        print("Removed \(transactions.count) StoreKit transactions")
    }

    func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
        print("SKPaymentTransaction failed to restore through SKPaymentQueue: \(error.localizedDescription)")
    }
}

我的日志和分析显示,续订一直是通过观察者队列处理的,但这个数字似乎明显低于 iTunes Connect 中显示的实际续订数量。

从 iOS 9 开始,NSNotificationCenter 将自动停止向已被释放的观察者发送通知(source)。

所以我想知道,是否有可能我的单例正在被系统释放,以便 SKPaymentTransactionObersver 也被删除?

或者这个单例(及其观察者状态)是否保证保留到应用程序终止?

最佳答案

SKPaymentQueue/SKPaymentTransactionObserver 文档,具体来说,状态:

// Observers are not retained. The transactions array will only be synchronized with the server while the queue has observers. This may require that the user authenticate.

open func add(_ observer: SKPaymentTransactionObserver)
open func remove(_ observer: SKPaymentTransactionObserver)

关于ios - 观察者是否被 Swift 单例永久保留?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43851737/

相关文章:

ios - 在需要的初始化中有 fatalError 可以吗?(编码器 aDecoder : NSCoder) when I don't use Storyboards?

ios8 - 为什么 SKStoreProductViewController loadProductWithParameters 不会在 iOS 8.0.2 上为 Apple 应用测试人员调用其completionBlock?

ios - 使用 UIActivityViewController 发送的 UIImage 的控制文件名

ios - 如何将 iOS 11 控制中心中的屏幕截图转发到您的应用程序?

ios - 如何在设定的时间段内运行一个 Action ?

iOS:使用自动续订订阅去除广告

ios - StoreKit 的 SKStoreProductViewController 在导航栏和 View 之间留有空间?

android - 我的 Facebook 应用程序也可以在 iOS/android 应用程序中运行?

arrays - 有关如何在 swift 中实现 Slice<T> 的任何提示吗?

ios - 在 iOS 中从 GMT 转换时间表现异常(反向)