应用内购买iOS 6
我正在尝试为iOS 6实施应用程序内购买,以下是我的参考点。我对Ray的代码所做的一个重大改变是,我有一个按钮,用户只需点击一个应用内购买,而不是为其创建自定义表视图。我似乎无法让它工作,我一直在工作应用内购买iOS 6,ios,objective-c,xcode,in-app-purchase,Ios,Objective C,Xcode,In App Purchase,我正在尝试为iOS 6实施应用程序内购买,以下是我的参考点。我对Ray的代码所做的一个重大改变是,我有一个按钮,用户只需点击一个应用内购买,而不是为其创建自定义表视图。我似乎无法让它工作,我一直在工作 -[__NSMallocBlock__ allObjects]: unrecognized selector sent to instance 0x1d5846d0 2012-10-03 00:03:25.715 myapp[752:907] *** Terminating app due to
-[__NSMallocBlock__ allObjects]: unrecognized selector sent to instance 0x1d5846d0
2012-10-03 00:03:25.715 myapp[752:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSMallocBlock__ allObjects]: unrecognized selector sent to instance 0x1d5846d0'
我相信这个问题正在发生
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler
ray和我分别实现了两个助手类。我只更改了应用程序id号。这些类称为IAPHelper.h/m和RageIAPHelper.h/m
我已经发布了代码,我认为错误发生的地方并不长。如果有人能帮助我,我已经为此工作了大约4个小时了。
先谢谢你
内部purchaseViewController
名为IAPHelper.m的内部助手方法
如果
-(void)requestProdcutsWithCompletionHandler:(RequestProductsCompletionHandler)
completionHandler{
....
{
在第一次调用完成之前调用两次。原因是使用了SKProductsRequestDelegate,并在收到响应时调用以下函数:
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
(SKProductsResponse *)response{
...
_completionHandler(YES, availableProducts)
_completionHandler = nil;
}
请注意,在处理响应后,\ u completionHandler是如何设置为nil的。好的,当下一个响应来自对requestProductsWithCompletionHandler的重复调用时,\u completionHandler为nil并抛出异常。您可以通过两种方式修复此问题,一种是确保不以错误的方式多次调用该函数,另一种是使用一些逻辑来确保completionHandler未被使用:
-(void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler{
NSLog(@"Request Products");
if (!_completionHandler) {
NSLog(@"CompletionHandler called, new one was made");
_completionHandler = [completionHandler copy];
NSMutableSet * productIdentifiers = [NSMutableSet setWithCapacity:_products.count];
for (IAPProduct * product in _products.allValues) {
product.availableForPurchase = NO;
[productIdentifiers addObject:product.productIdentifier];
}
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
_productsRequest.delegate=self;
[_productsRequest start];
}else{
NSLog(@"Duplicate call!");
}
}
productRequest首先检查以确保_completionhandle为nil,如果不是,则会忽略该请求,因为处理程序正在使用中。如果
-(void)requestProdcutsWithCompletionHandler:(RequestProductsCompletionHandler)
completionHandler{
....
{
在第一次调用完成之前调用两次。原因是使用了SKProductsRequestDelegate,并在收到响应时调用以下函数:
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
(SKProductsResponse *)response{
...
_completionHandler(YES, availableProducts)
_completionHandler = nil;
}
请注意,在处理响应后,\ u completionHandler是如何设置为nil的。好的,当下一个响应来自对requestProductsWithCompletionHandler的重复调用时,\u completionHandler为nil并抛出异常。您可以通过两种方式修复此问题,一种是确保不以错误的方式多次调用该函数,另一种是使用一些逻辑来确保completionHandler未被使用:
-(void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler{
NSLog(@"Request Products");
if (!_completionHandler) {
NSLog(@"CompletionHandler called, new one was made");
_completionHandler = [completionHandler copy];
NSMutableSet * productIdentifiers = [NSMutableSet setWithCapacity:_products.count];
for (IAPProduct * product in _products.allValues) {
product.availableForPurchase = NO;
[productIdentifiers addObject:product.productIdentifier];
}
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
_productsRequest.delegate=self;
[_productsRequest start];
}else{
NSLog(@"Duplicate call!");
}
}
productRequest首先检查以确保_completionhandle为nil,如果不是,则会忽略该请求,因为处理程序正在使用。我决定为未来的读者发布一个答案,而不是评论。我也在学习教程,但在实现中发现了一个问题,导致了崩溃 他为我声明了两个有问题的实例变量,至少: _productIdentifiers和_purchasedProductIdentifiers 因为在初始化singleton时,他给他们分配了一个将被释放的对象。也许这是因为我的项目没有使用ARC,但我认为没有。在任何情况下,如果您从他的教程中更改此代码:
// Store product identifiers
/*_productIdentifiers = productIdentifiers; ----> This is the original code */
_productIdentifiers = [[NSSet alloc]initWithSet:productIdentifiers]; // Replace with this
// Check for previously purchased products
/*_purchasedProductIdentifiers = [NSMutableSet set]; ----> This is the original code*/
_purchasedProductsIdentifiers = [[NSMutableSet alloc]init]; //Replace with this
因为其他方法会释放对象。或者,您可以在声明中声明属性,然后使用对象的自动释放版本
我希望这对某些人有所帮助,我花了一段时间才弄明白这一点,可能是因为我刚刚阅读了教程。我决定为未来的读者发布一个答案,而不是评论。我也在学习教程,但在实现中发现了一个问题,导致了崩溃 他为我声明了两个有问题的实例变量,至少: _productIdentifiers和_purchasedProductIdentifiers 因为在初始化singleton时,他给他们分配了一个将被释放的对象。也许这是因为我的项目没有使用ARC,但我认为没有。在任何情况下,如果您从他的教程中更改此代码:
// Store product identifiers
/*_productIdentifiers = productIdentifiers; ----> This is the original code */
_productIdentifiers = [[NSSet alloc]initWithSet:productIdentifiers]; // Replace with this
// Check for previously purchased products
/*_purchasedProductIdentifiers = [NSMutableSet set]; ----> This is the original code*/
_purchasedProductsIdentifiers = [[NSMutableSet alloc]init]; //Replace with this
因为其他方法会释放对象。或者,您可以在声明中声明属性,然后使用对象的自动释放版本
我希望这对其他人有所帮助,我花了一段时间才弄明白,可能是因为我刚刚学习了教程。你有没有修复过这个问题?你有没有修复过这个问题?你的代码对我来说也崩溃了。对我来说,_productsRequest=[[SKProductsRequest alloc]initWithProductIdentifiers:_productIdentifiers]中有一个僵尸NSSet;你知道这个教程是否正确吗?这个片段帮助我谢谢你,但不是针对同一个问题。有时,我太快调用了两次requestProductsWithCompletionHandler,导致excbadaccess,而不是问题中的sigbart无法识别的选择器。您的代码也会崩溃。对我来说,_productsRequest=[[SKProductsRequest alloc]initWithProductIdentifiers:_productIdentifiers]中有一个僵尸NSSet;你知道这个教程是否正确吗?这个片段帮助我谢谢你,但不是针对同一个问题。有时,我调用两次requestProductsWithCompletionHandler太快,导致excbadaccess,而不是问题中的sigbart无法识别的选择器。