应用内购买iOS 6

应用内购买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

我正在尝试为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 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无法识别的选择器。