在 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 个或更多级别的因子