从不同视图添加和删除视图时的EXC_BAD_ACCESS

时间:2013-01-24 22:34:26

标签: iphone ios exc-bad-access

我创建了一个带有游戏商店视图和视图控制器的游戏。 可以通过菜单(ViewController.m)和Game Over屏幕(GameViewController.m)访问商店。

我的问题是,如果我在菜单中显示了一次商店,然后玩游戏并通过屏幕访问游戏中的商店并尝试购买东西,那么应用程序会在没有太多信息的情况下崩溃EXC_BAD_ACCESS错误。 (打破

[[SKPaymentQueue defaultQueue] addPayment:lPayment];
尝试购买IAP时,在我的ShopViewController中的ButtonPressed操作中

行。

我的观点设置如下:

菜单视图 - > Ladderview - > Gameview - > ShopView

菜单视图 - > Shopview

希望你能帮助我查明错误,

编辑-----------

似乎我可以从菜单中重现错误 - > Shopview不使用游戏视图。我可以通过按“购买按钮”,按取消,导航回菜单,返回商店,然后重复来完成此操作。在第3-4次尝试时,它在同一行崩溃。这是按下整个按钮的方法:

- (void)buyButtonPressed:(UIButton *)pButton {
    NSInteger lTag = [pButton tag];
    //////NSLog(@"Button tag: %i"), lTag;

    Reachability *lReachability = [Reachability reachabilityForInternetConnection];
    NetworkStatus lCurrentNetworkStatus = [lReachability currentReachabilityStatus];
    if (lCurrentNetworkStatus != NotReachable) {
        if ([SKPaymentQueue canMakePayments]) {
            SKPayment *lPayment = [SKPayment paymentWithProduct:[mPriceArray objectAtIndex:lTag]];
            [[SKPaymentQueue defaultQueue] addPayment:lPayment];
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

        } else {
            [self showAlertViewWithText:@"Purchases are disabled. Please check your settings for General -> Restrictions -> In-App Purchases and try again." andTitle:@"Warning"];
        }
    } else {
        [self showAlertViewWithText:@"No network connection!" andTitle:@"Warning"];
    }
}

所以看起来lPayment正在被取消分配。我甚至试图设置

mProductIds = nil;
mPriceArray = nil;

当我删除商店视图时,试图强制它在我重新加载商店时再次分配它,但没有任何运气。

由于

3 个答案:

答案 0 :(得分:3)

你的问题是一个悬垂的指针。 EXC_BAD_ACCESS是CPU呻吟,您正在处理访问权限区域之外的不存在的内存或内存。原因是缺乏对象的保留,导致早期释放,然后被覆盖。在那个时候(可能被延迟),指针将指向垃圾,其解除引用(类检查)导致抛出EXC_BAD_ACCESS。使用@try无法捕获此错误。这里有一个假设,堆栈本身是腐败的,导致继续是不可能的(尽管很可能不是这种情况),这会抛出调试器进行旋转,其当前的状态输出在许多领域已经缺乏。当CPU重置重要寄存器并执行长跳转时,这就像无法控制的无政府状态。

考虑自动引用计数。在您已经存在的情况下,请考虑主机对象不保留类似委托的属性。任何逻辑上可以包含self的属性都不会保留存储在其中的任何值。 ARC不会帮助你。

在你的情况下:defaultQueue可能是好的。 lPayment可能已被解除分配。

答案 1 :(得分:1)

首先尝试在启用NSZombie时跟踪问题。在EXC_BAD_Access的情况下问题一段时间(NSZombie)跟踪解除分配的对象变得比简单猜测问题所在的地方更有用。

答案 2 :(得分:1)

很难从提供的信息中得知,但可能如下:您的陈述

SKPayment *lPayment = [SKPayment paymentWithProduct:[mPriceArray objectAtIndex:lTag]];  

实例化SKPayment对象,并将其交给当前的自动释放池。如果此池不存在(如果代码在没有显式设置自动释放池的单独线程中运行,则可能就是这种情况),该对象将立即再次释放,并且您的语句

[[SKPaymentQueue defaultQueue] addPayment:lPayment];  

访问无效内存。