Iphone 使用[UIView animateWithDuration:animations:completion]执行错误访问

Iphone 使用[UIView animateWithDuration:animations:completion]执行错误访问,iphone,ios,exc-bad-access,Iphone,Ios,Exc Bad Access,好的。。下面是整个场景 其概念是在屏幕上显示多个订单,用户可以向左或向右滑动以查看下一个订单。接受或拒绝订单后,订单视图将向下滑动,并替换为旁边的视图或上一个视图(如果订单已结束) 我有一个选项卡视图,其中包含一个简单的UIScrollView和两个按钮(接受和拒绝)。在ViewDidLoad中,我准备了一个订单数组,用Nib文件初始化ViewController(等于总订单),并将这些ViewController的视图添加到ScrollView中,并设置ScrollView的内容大小等。。(用

好的。。下面是整个场景

其概念是在屏幕上显示多个订单,用户可以向左或向右滑动以查看下一个订单。接受或拒绝订单后,订单视图将向下滑动,并替换为旁边的视图或上一个视图(如果订单已结束)

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

当用户点击AcceptButton时,将执行一个动画,将UIScrollView中的可见视图向下滑动,然后将其从超级视图中移除

动画代码执行如下

    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];
            }
        }
    }];
动画工作正常,但移除的视图会被解除分配

当接受最后一个视图时,应用程序在[UIView animateWithDuration:animations:completion]方法调用时崩溃,exc_bad_访问正好发生

NSZombies无法检测到确切的泄漏点/原因

经过广泛的研究,我认为这可能是由于使用了积木。。内存管理很好,因为如果我过度扩展了任何内容,NSZombies会指出这一点

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

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

一件有趣的事情是,如果我先关闭第二个订单,然后接受第一个订单,代码也可以正常工作=(确实非常混乱!)


该项目的目标是iOS 4.0

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

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

将被调用此属性的访问器方法替换,您和我们将确切了解ivar
控制器是否保留。这对您正在使用的所有其他ivar有效:
lastPageMoving
of Pages
totalPages
CurrentPages
等-只需将它们更改为属性即可并确保其正确的内存管理。

设备和模拟器分别运行5.0.1和5.1 iOS。!!XCode为4.3,基本iOS SDK为5.1使用
\uuuuuuuuuuuuuuuunretained MyClass*weakSelf=weakSelf;
然后用weakSelf替换块中的
self
,因为如果释放self,对self的引用将崩溃d当块仍在运行时(同样,不保留您不拥有的东西是有意义的)。这只是一种良好的做法,不一定是您描述的错误。EXC_BAD_访问并不总是来自于发送无效指针的消息,有时它下面是一个C库(不知道这里是否是这种情况)。作为评论发布,因为我没有阅读所有内容,也不知道问题出在哪里。好的..很好..通过将所有局部变量转换为控制器的实例属性,错误似乎消失了..谢谢..但我真的想知道问题出在哪里=/