在 App Purchase/View Controller Crash: Message sent to deallocated instance

Posted

技术标签:

【中文标题】在 App Purchase/View Controller Crash: Message sent to deallocated instance【英文标题】:In App Purchase/View Controller Crash: Message sent to deallocated instance 【发布时间】:2012-08-11 17:10:12 【问题描述】:

我的视图控制器上有一个按钮,用于显示我的应用内购买商店。

storeSinglePlayer *ssp = [[storeSinglePlayer alloc] initWithNibName:@"storeSinglePlayer" bundle:nil];

//Animation Code

CATransition* transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush; 
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition forKey:nil];

[self.navigationController pushViewController:ssp animated:NO];

导航控制器成功将这个商店推送到屏幕上。商店有一个执行以下代码的后退按钮:

[self.request cancel];
self.request.delegate = nil;
self.request = nil;
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];

CATransition* transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromBottom; 
[self.navigationController.view.layer addAnimation:transition forKey:nil];


[self.navigationController popViewControllerAnimated:NO];

这也成功执行。但是,如果我现在再次单击按钮以显示商店视图控制器,我会收到以下消息:

-[storeSinglePlayer respondsToSelector:]: message sent to deallocated instance 0xd642df0

这确实是一个非常著名的问题。正如您将在上面的代码中注意到的那样,我已经合并了我在 *** 上遇到的各种帖子的建议。已实现以下代码:

[self.request cancel];
self.request.delegate = nil;
self.request = nil;
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];

我的属性和相应的合成设置为:

@property (nonatomic, strong) SKProductsRequest *request;
@synthesize request = _request;

我不知道,为什么会崩溃!

P.S:该项目已启用 ARC。

【问题讨论】:

确保你没有发布它两次..?还是你在使用 arc..? 抛出异常时查看堆栈可能很有用。如果您自己不调用 respondsToSelector:,则可能会在将 ssp 用作某种代表时发生这种情况。 您遇到的例外是一个非常普遍的例外; 您需要使用调试器设置断点以在抛出异常时停止。 然后您可以查看调用堆栈(正如 Phillip Mills 建议的那样)并找出您的代码正在做什么来触发异常. 那么我们将有足够的信息来解决这个问题。 @benzado:我使用代码处理多个方向:[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"storeSinglePlayerLandscape"] owner:self options:nil]; [self viewDidLoad];会不会是这个问题造成的? 【参考方案1】:

在 ARC 发布后,有东西在调用您的 ssp。您发布的代码没有说明发生的位置。

最有可能解决问题的一件事是在类声明中保留对 ssp 的成员变量+属性的引用,而不是每次单击按钮时都创建一个新的引用。只需在您的第一个视图控制器加载并重用它时初始化一次。

如果您想进一步调查,可以尝试注释掉设置过渡的块,看看它是否仍然崩溃。可能在 ssp 发布后,navigationcontroller 会进行一些调用。

【讨论】:

感谢您的回复。事实上,我可以通过应用所有可能的解决方案来缩小实际问题的范围。【参考方案2】:

当一个消息被发送到一个被释放的实例时,一个对象从内存中被释放并且你试图再次使用它。 ARC 必须释放对象,因为它会自动检测到您不再需要它。尝试将以下内容之一添加到您的头文件中。

@property (nonatomic, strong) storeSinglePlayer *ssp;

storeSinglePlayer *__strong ssp;

上面最重要的词是strong。它告诉 ARC 你想保留这个对象供以后使用。

【讨论】:

【参考方案3】:

我搞砸了。我正在使用以下代码处理多次旋转:

[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"storeSinglePlayerLandscape"] owner:self options:nil];

[self viewDidLoad];

我现在意识到,这不是最佳做法,因为它会多次调用 viewDidLoad。不过,这并不是问题的真正原因。当商店只显示几次并返回到前一个视图控制器时,它工作正常。但是说在 10-15 次之后,有太多的请求会随产品返回,因此会发送错误,“消息已发送到已释放的实例”。

我把代码注释掉了,现在可以正常使用了。

我知道,这是一个非常典型的问题,大多数用户可能不会遇到。但是以防万一,您使用了像我这样的错误代码,可能这些信息有效!

【讨论】:

以上是关于在 App Purchase/View Controller Crash: Message sent to deallocated instance的主要内容,如果未能解决你的问题,请参考以下文章

找不到类“App\Http\Controllers\App\Model”

带有数字变量的`对比度<-`(`*tmp*`,value = contr.funs[1 + isOF[nn]])中的错误[重复]

`contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) 中的错误:对比只能应用于具有 2 个或更多级别的因子

django的路由系统

12c5a60s2单片机ADC采样程序详解(每一句话都是啥意思)

beego4---web项目结构