1

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

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;

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

PS:该项目启用了ARC。

4

3 回答 3

2

在 ARC 发布后,某些东西正在调用您的 ssp。您发布的代码并不清楚发生在哪里。

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

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

于 2012-08-15T12:01:56.553 回答
0

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

@property (nonatomic, strong) storeSinglePlayer *ssp;

或者

storeSinglePlayer *__strong ssp;

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

于 2012-08-15T12:01:18.423 回答
0

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

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

[self viewDidLoad];

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

我注释掉了代码,现在它工作正常。

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

于 2012-08-16T18:26:44.577 回答