Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 应用程序因UITabBarController和应用程序内购买而崩溃_Ios_Uitabbarcontroller_In App Purchase - Fatal编程技术网

Ios 应用程序因UITabBarController和应用程序内购买而崩溃

Ios 应用程序因UITabBarController和应用程序内购买而崩溃,ios,uitabbarcontroller,in-app-purchase,Ios,Uitabbarcontroller,In App Purchase,我的应用程序用于应用程序购买和我的参考 当我通过块从服务器加载产品时,同时切换到UITabBarController内的其他选项卡,当加载产品时,应用程序崩溃 这是我的密码 //Load products from server [[LAInAppHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) { if (success) { //

我的应用程序用于应用程序购买和我的参考

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

这是我的密码

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

如果我删除这些行,我可以在任何选项卡之间切换。应用程序崩溃时不会抛出任何东西,即使我启用了僵尸对象。只是访问错误

中的
LAInAppHelper
的实现中存在一个问题:helper将您的应用程序视为非并发

发生的情况如下:
LAInAppHelper
的共享实例有一个
sharedInstance
,它拥有
\u completionHandler
(除其他外)

requestProductsWithCompletionHandler:
方法分配
\u completionHandler
已传入的块的副本。对于第一个请求,这是正常的,但是如果另一个请求“正在运行”,ARC将由于该重新分配而释放该另一个请求的完成块。如果切换到的选项卡启动了并发请求,则初始请求将返回到已释放的块,从而导致未定义的行为,并可能导致崩溃

要解决此问题,您需要将类分成两部分,一部分包含所有请求的公共项(即,
\u productIdentifiers
\u purchasedProductIdentifiers
)和请求特定项(
\u productsRequest
\u 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;
}
您还需要创建一个块来包装
\u completionHandler
,如下所示:

- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
    __block LAInAppHelperRequest *req = [[LAInAppHelperRequest alloc] initWithHelper:self andCompletionHandler:^(BOOL success, NSArray *products) {
         completionHandler(success, products);
         req = nil;
    }];
}

在加载选项卡时禁用切换选项卡的可能性如何?如果我想同时执行这两项操作。@crz请仔细检查您的项目是否正在使用ARC(自动引用计数)。如果你没有,那代码几乎肯定会崩溃。@JamesHolderness当然我使用的是ARCall仍然会崩溃,请检查下面的答案@john.k.doeso非常感谢@dasblinkenlight,你的答案对我的知识非常有用,但不能解决我的问题。我找到了应用程序崩溃的原因,因为我点击了TabBarController上的另一个按钮,该选项卡调用了另一个时间方法[[LAInAppHelper sharedInstance]requestProductsWithCompletionHandler:^(BOOL success,NSArray*products)获取购买的产品列表。所以应用程序崩溃了!再次感谢您抽出时间回答我的问题!有什么办法帮我再次调用该方法获取购买的产品列表吗product@crz看起来崩溃正是我当时提到的问题的结果——从另一个选项卡同时调用
sharedInstance
。您尝试过imp吗我的计划如何?进展如何?