我的视图控制器上有一个按钮,用于显示我的In App Purchases商店。
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
这确实是一个非常着名的问题。正如您在上面的代码中所注意到的,我已经在stackoverflow中包含了我遇到的各种帖子的建议。已实施以下代码:
[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。
答案 0 :(得分:2)
在ARC发布后,有些东西正在调用你的ssp。您发布的代码并未明确说明发生的位置。
最有可能解决问题的一件事是在类声明中保留带有成员变量+属性的引用到ssp,而不是每次单击按钮时创建一个新引用。当你的第一个viewcontroller加载并重新使用它时,只需初始化它。
如果您想进一步调查,可以尝试注释掉设置过渡的块,看看它是否仍然崩溃。也许导航控制器在ssp释放后进行一些调用。
答案 1 :(得分:0)
当消息发送到解除分配的实例时,会从内存中释放一个对象,并且您尝试再次使用它。 ARC必须释放对象,因为它会自动检测到您不再需要它。尝试将以下其中一项添加到头文件中。
@property (nonatomic, strong) storeSinglePlayer *ssp;
或
storeSinglePlayer *__strong ssp;
上面重要的一句话是强大。它告诉ARC你想保留这个对象供以后使用。
答案 2 :(得分:0)
我到了搞砸的地方。我正在使用以下代码处理多个旋转:
[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"storeSinglePlayerLandscape"] owner:self options:nil];
[self viewDidLoad];
我现在意识到,这不是最好的做法,因为它多次调用viewDidLoad。不过,这不是问题的真正原因。当商店只显示几次并返回到前一个视图控制器时,它工作正常。但是在10-15次之后说,有太多的请求将返回产品,因此发送错误,“消息发送到解除分配的实例”。
我注释掉了代码,现在工作正常。
我知道,这是一个非常典型的问题,大多数用户可能不会面对。但为了以防万一,你使用了像我这样的实现了一些不好的代码,可能这个信息有效!