iPhone-SKProductsRequest和;已发送到解除分配实例的消息“;
我在执行非应用程序购买时遇到麻烦。我的购买实现是在模态视图控制器(AppUpgradeViewController)中实现的,我从另一个模态视图中演示了它。我是这样做的:iPhone-SKProductsRequest和;已发送到解除分配实例的消息“;,iphone,Iphone,我在执行非应用程序购买时遇到麻烦。我的购买实现是在模态视图控制器(AppUpgradeViewController)中实现的,我从另一个模态视图中演示了它。我是这样做的: AppUpgradeViewController * appUpgradeViewController = [[AppUpgradeViewController alloc] init]; appUpgradeViewController.modalTransitionStyle = UIModalTransitionStyl
AppUpgradeViewController * appUpgradeViewController = [[AppUpgradeViewController alloc] init];
appUpgradeViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
appUpgradeViewController.delegate = self;
[self presentModalViewController:appUpgradeViewController animated:YES];
[appUpgradeViewController release];
然后,在我的升级视图中,我执行以下操作:
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
NSSet *productIdentifiers = [NSSet setWithObject:kInAppPurchaseProUpgradeProductId];
self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
self.productsRequest.delegate = self;
[productsRequest start];
然后我实施了
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
我的工作:
[self.productsRequest release];
然后我有其他需要的方法
问题是,当我显示模态并迅速将其关闭时,几秒钟后,我在控制台上看到以下内容(我启用了NSZombieEnabled):
我想这与产品请求有关,但我不知道如何调试或修复它。看起来,请求的答案在该控制器被解除(和解除分配)之后才到达该控制器,但我不知道如何防止它在解除/解除分配后接收消息。
谢谢你的帮助 是因为你这样做:
[appUpgradeViewController release];
太早了
试着在任何类的dealloc方法中实现它。
当然,前提是您不会多次分配它。这还需要您将声明移动到类标题中。我想这是因为您已经发布了productsRequest,但似乎您还没有将指针设置为
nil
,这意味着它仍然指向现在无效的内存位置
如何定义productsRequest
属性?如果它有保留
选项,则代替:
[self.productsRequest release];
您需要执行以下操作:
self.productsRequest = nil; // Property will do the release for you.
[self.productsRequest release];
self.productsRequest = nil; // Or else some might access this pointer,
// which now might point to nirvana.
如果它有assign
选项,则需要执行以下操作:
self.productsRequest = nil; // Property will do the release for you.
[self.productsRequest release];
self.productsRequest = nil; // Or else some might access this pointer,
// which now might point to nirvana.
您可能忘记在
AppUpgradeViewController
的dealloc
中取消请求委托:
- (void)dealloc {
...
productsRequest.delegate = nil;
[productsRequest release], productsRequest = nil;
...
[super dealloc];
}
我也有同样的问题。不是使用模式视图,而是使用导航控制器堆栈上的推送视图。当我在通过
SKProductsRequest
加载产品信息之前快速导航回时,它还会向我抛出一条消息,该消息发送到解除分配的实例
异常。我通过调用SKProductsRequest对象上的cancel
方法(请参阅)解决了这个问题
除此之外,我还将委托设置为nil
这是我的产品请求:
NSSet *productIdentifiers = [NSSet setWithObject:@"MY_IDENTIFIER"];
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];
这就是我在dealloc方法中调用的取消它的方法
productsRequest.delegate = nil;
[productsRequest cancel];
productsRequest = nil;
我还从SKPaymentQueue
中删除了观察者,如中所述
Swift 3 如果您启动了请求,最好关闭它。这是一种安全的Swift方式
// strong reference at top of class
var productRequest: SKProductsRequest!
// at some point you will fetch products
// on deallocating the window
if productRequest != nil {
productRequest.cancel()
productRequest.delegate = nil
}
它的定义如下:@property(非原子,retain)SKProductsRequest*productsRequest;在这种情况下,您所需要做的就是
self.productsRequest=nil代码>。不要做[self.productsRequest release]代码>,这将导致内存错误。它的定义如下:@property(非原子,retain)SKProductsRequest*productsRequest;但我只在“-(void)productsRequest:(SKProductsRequest*)request-didReceiverResponse:(SKProductsResponse*)response”方法中释放它,所以在控制器收到响应之前不会释放它。若我在控制器收到响应之前立即关闭modal,则不会发生这种情况。但我尝试在我的dealloc方法中执行“[self.productsRequest release]”,错误为“***-[SKProductsRequest release]:消息已发送到解除分配的实例0x20c010”。我曾在dealloc中尝试过这种方法:“self.productsRequest.delegate=nil;”,但错误是:“***-[SKProductsRequest setDelegate:]:消息已发送到deallocated实例0x2f3090”。当我在dealloc中只执行“productsRequest=nil;”时,我会遇到与前面相同的错误:***-[AppUpgradeViewController respondsToSelector:]:消息发送到解除分配的实例0x2f9590”最终解决!我认为dealloc方法中正确的指令集是:self.productsRequest.delegate=nil;[self.productsRequest取消];self.productsRequest=nil;[[SKPaymentQueue defaultQueue]removeTransactionObserver:self];我不认为我做得太早。很可能有什么东西在调用控制器的方法,但它肯定不能。我有同样的问题,但下面的解决方案都不适合我。我已经启用了ARC。有什么建议吗?这花了很长时间才弄明白。Enable Zombie objects捕获到这条消息,该消息将我抛出-[IAPurchaseViewController retain]:发送到解除分配实例的消息
。非常感谢。我不明白为什么你(和我)在取消时必须nil
代表。它必须在所有引用都消失后立即消失,但某些东西使它与要回调的委托引用一起保持活动状态。。。