iphone - EXC_BAD_ACCESS 使用 [UIView animateWithDuration :animations:completion]

标签 iphone ios exc-bad-access

好的..这是整个场景

这个概念是在一个屏幕上显示多个订单,用户可以向左或向右滑动以查看下一个订单。一旦订单被接受或拒绝,订单 View 就会向下滑动,并被旁边的 View 取代,如果订单结束,则被替换为上一个 View 。

我有一个标签栏 View ,其中包含一个简单的 UIScrollView 和几个按钮(接受和拒绝)。在 ViewDidLoad 中,我准备了一个订单数组,使用 Nib 文件初始化 ViewController(等于总订单)并将这些 ViewController 的 View 添加到 ScrollView 并设置 ScrollView 的内容大小等。(用于垂直和水平滚动)

当用户点击 AcceptButton 时,将执行动画,将 UIScrollView 中的可见 View 向下滑动,然后将其从 super View 中移除。

动画代码执行如下。

    BOOL lastPage = NO;
    BOOL ordersEmpty = NO;
    if (self.views.count == 1){
        ordersEmpty = YES;
        lastPage = YES;
    }

    UIViewController *controller2;
    if (self.views.count == page+1 && !ordersEmpty){
        lastPage = YES;
        controller2 = [self.views objectAtIndex:page-1];
    } else if (!ordersEmpty){
        controller2 = [self.views objectAtIndex:page+1];
    }
    [UIView animateWithDuration:1.5 animations:^{
        CGRect frame = controller.view.frame;
        frame.origin.y = frame.size.height + 100;
        controller.view.frame = frame;

        if (lastPage == NO){
            CGRect frame2 = controller2.view.frame;
            frame2.origin.x = frame.origin.x;
            controller2.view.frame = frame2;
        }else{
            // [self.scrollView scrollRectToVisible:controller2.view.frame animated:YES];
        }

    } completion:^(BOOL value){
        [controller.view removeFromSuperview];
        [self.views removeObject:controller];
        totalPages.text = [NSString stringWithFormat:@"%i", self.views.count];
        // currentPage.text = [NSString stringWithFormat:@"%i", 
        self.pageControl.numberOfPages = self.views.count;
        if (lastPage && !ordersEmpty){
            [self.scrollView scrollRectToVisible:controller2.view.frame animated:YES];
            lastPageMoving = YES;
        }else if (ordersEmpty){
            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
            label.text = @"There are currently no notifications";
            label.textAlignment = UITextAlignmentCenter;
            label.center = CGPointMake(self.scrollView.frame.size.width/2, self.scrollView.frame.size.height/3);
            [self.scrollView addSubview:label];
            [label release];
            ofPages.text = @"";
            totalPages.text = @"";
            currentPage.text = @"";
            self.scrollView.contentSize = CGSizeMake(320, 267);
        }

        int i = 0;
        for (UIViewController *c in self.views)
        {
            c.view.frame = CGRectMake(self.scrollView.frame.size.width * i, 0, c.view.frame.size.width, c.view.frame.size.height);
            i++;
        }

        if (controller2 != nil)
        {
            if ([controller2 isKindOfClass:[CancelledController class]]) {
                self.acceptButton.hidden = YES;
                [self.declineButton setTitle:@"Close" forState:UIControlStateNormal];
                [self.declineButton setTitle:@"Close" forState:UIControlStateHighlighted];
            }else{
                self.acceptButton.hidden = NO;
                [self.declineButton setTitle:@"Decline" forState:UIControlStateNormal];
                [self.declineButton setTitle:@"Decline" forState:UIControlStateHighlighted];
            }
        }
    }];

动画工作正常,移除的 View 被释放

当接受最后一个 View 时,应用程序恰好在 [UIView animateWithDuration:animations:completion] 方法调用时崩溃并显示 exc_bad_access。

NSZombies 没有检测到确切的泄漏点/原因..

经过大量研究,我认为这可能是由于使用了 block 。内存管理很好,因为如果我过度释放任何东西,NSZombies 会指出这一点。

(虽然代码在模拟器中运行良好 - 没有任何错误)

我制作了一个视频来演示动画是如何工作的。它是模拟器的,所以这里没有错误,但是,当我在设备上运行它时,只要我按下关闭按钮,应用程序就会崩溃。

有趣的是,如果我先关闭第二个订单,然后再接受第一个订单,代码也能正常工作=(确实非常令人困惑..!!

http://www.mediafire.com/?w1up9g9u6w0ucrn

该项目针对 iOS 4.0

最佳答案

您可以首先将声明 UIViewController *controller2 更改为 UIViewController *controller2 = nil;,然后最好仅使用属性,因此行:

[controller.view removeFromSuperview];
[self.views removeObject:controller];

将被调用此属性的访问器方法替换,您和我们将确切知道是否保留了 ivar controller。这对您正在使用的所有其他 ivars 都有效:lastPageMovingofPagestotalPagescurrentPage 等。 - 只需将它们更改为属性并确保对其进行适当的内存管理。

关于iphone - EXC_BAD_ACCESS 使用 [UIView animateWithDuration :animations:completion],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10862766/

相关文章:

ios - 添加 NSArray 到 NSMutableArray

ios - CLLocationManager 在后台时不更新,并且得到困惑的位置坐标 Swift

c++ - 试图读取AIFF文件意外错误与指针位置等有关

iphone - Exc Bad Access 关闭 View Controller

iphone - 监听器/观察器方法通知模型更改的优缺点

iphone - 异步 iOS 网络库设计

ios - 如何转换 iPhone 应用程序以支持 iPad

ios - 使用 dispatch_async 时的 EXC_BAD_ACCESS

iphone - 在用户 header 搜索路径中使用 $(BUILT_PRODUCTS_DIR)

iphone - 如何使用键值对 NSMutableDictionary 进行排序?