iOS StoreKit最佳实践:SKPaymentQueue观察者移除时机的安全性疑问
Great question—this is a super common point of confusion with StoreKit, so let’s break down what’s going on here and what the safest approach is.
First, let’s cut to the chase: this scenario is safe, and in fact, you probably don’t need to remove the SKPaymentQueue observer in either applicationWillTerminate or applicationDidEnterBackground for your app-level observer. Here’s why:
SKPaymentQueue handles observer cleanup automatically for app termination
The
SKPaymentQueueholds a weak reference to your observer (usually your AppDelegate or a dedicated in-app purchase manager singleton). When your app is terminated—whether it gracefully runsapplicationWillTerminateor gets killed by the system to free up memory—your observer object will be deallocated, and the queue will automatically remove it from its observer list. No memory leaks, no dangling references, no issues here.Removing observers in
applicationDidEnterBackgroundis actually riskyIf you remove the observer when the app enters the background, you’ll miss critical transaction callbacks. For example, if a user completes an in-app purchase while your app is in the background, the
SKPaymentQueuewill try to notify your observer—but if you’ve already removed it, you won’t get that update. This can lead to out-of-sync purchase states, frustrated users, and even rejected transactions that never get processed.Apple’s "remove observer" guidance applies to temporary observers, not app-level ones
The official StoreKit documentation mentions removing observers primarily for short-lived objects (like view controllers that observe transactions only while they’re on screen). For an app-level observer that lives for the entire lifecycle of your app, there’s no need to manually remove it—its lifecycle is tied directly to the app’s own lifecycle.
A more robust practice to follow:
- Add your
SKPaymentQueueobserver once, when your app launches (indidFinishLaunchingWithOptionsfor AppDelegate, or in the initializer of your IAP manager singleton). - Only remove observers if they’re tied to objects that get deallocated during the app’s runtime (like a checkout view controller—remove its observer in
deinit).
This way, you’ll never miss transaction callbacks, and you won’t have to worry about whether applicationWillTerminate gets called or not.
内容的提问来源于stack exchange,提问作者user3621075

