我的应用程序用于购买应用程序,我的引用是here

当我按块从服务器加载产品时,同时我切换到UITabBarController内的其他选项卡,加载产品时应用崩溃

这是我的代码

//Load products from server
[[LAInAppHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) {
    if (success) {
        // even i do nothing in here app till crashed
    }
}];

如果删除此行,则可以在任何选项卡之间切换。崩溃时应用程序不会抛出任何异常,即使我启用了Zombie对象也是如此。不好访问

最佳答案

tutorial that you linked中的LAInAppHelper的实现存在问题:帮助程序将您的应用程序视为非并行应用程序。

这是怎么回事:LAInAppHelper的共享实例有一个sharedInstance,它拥有_completionHandler(除其他外)。
requestProductsWithCompletionHandler:方法为_completionHandler分配了已传递的块的副本。对于第一个请求,这是可以的,但是如果另一个请求处于“运行中”状态,则由于此重新分配,ARC将释放该另一个请求的完成块。如果切换到的选项卡启动并发请求,则初始请求将返回到已释放的块,从而导致不确定的行为,甚至可能导致崩溃。

要解决此问题,您需要将类分为两部分-一部分包含所有请求通用的项(即_productIdentifiers_purchasedProductIdentifiers)和特定于请求的项(_productsRequest_completionHandler)。

第一类的实例(我们将其称为LAInAppHelper)保持共享;第二类的实例(我们将其称为LAInAppHelperRequest)是在requestProductsWithCompletionHandler:方法内按请求创建的。

-(id)initWithHelper:(LAInAppHelper*)helper
    andCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
    if (self = [super init]) {
        _completionHandler = [completionHandler copy];
        _productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:helper.productIdentifiers]; // You will need to make productIdentifiers a property
        _productsRequest.delegate = self;
        [_productsRequest start];
    }
    return self;
}

您还需要创建一个包装_completionHandler的块,如下所示:
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
    __block LAInAppHelperRequest *req = [[LAInAppHelperRequest alloc] initWithHelper:self andCompletionHandler:^(BOOL success, NSArray *products) {
         completionHandler(success, products);
         req = nil;
    }];
}

09-30 14:25
查看更多