Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.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
Iphone 不清楚如何从另一个UIViewController中正确删除UIViewController_Iphone_Objective C_Ios - Fatal编程技术网

Iphone 不清楚如何从另一个UIViewController中正确删除UIViewController

Iphone 不清楚如何从另一个UIViewController中正确删除UIViewController,iphone,objective-c,ios,Iphone,Objective C,Ios,感谢您抽出时间(顺便说一句,这个问题主要涉及iOS 4.2.3,我知道将代码库移动到iOS 5可以解决其中一些问题,但是我们也希望为运行iOS 4的手机发布此应用。) 我有一个“MasterViewController”,负责呼叫和解除其他UIViewController 首先,我们触发一个新的: 在MasterViewController.m中 假设我们的randomNumber为0,它将ThinkOfViewController添加到子视图中(这是一个非常基本的屏幕,它基本上显示一些文本和一

感谢您抽出时间(顺便说一句,这个问题主要涉及iOS 4.2.3,我知道将代码库移动到iOS 5可以解决其中一些问题,但是我们也希望为运行iOS 4的手机发布此应用。)

我有一个“MasterViewController”,负责呼叫和解除其他UIViewController

首先,我们触发一个新的:

在MasterViewController.m中

假设我们的randomNumber为0,它将ThinkOfViewController添加到子视图中(这是一个非常基本的屏幕,它基本上显示一些文本和一些动画资源:

在ThinkOfViewController.m中

如您所见,动画序列完成后,我会向NSNotificationCenter(位于MasterViewController中)发布一条通知,以删除此viewController

在MasterViewController.m中

现在,一个picturePrimeViewController被加载并添加到子视图中,所有内容都加载并显示良好。现在,要获得一个新的素数,只需滑动一个新的素数

在picturePrimeViewController.m中

现在在animationDidStop:Method中,我再次将另一个通知发布到NSNotificationCenter,并返回到MasterViewController,以发出另一个prime的信号

在MasterViewController.m中

然而!在向右滑动时,视图动画正常,但是当ThinkOfViewController试图解除锁定它的UIViews时,我遇到了一个错误的访问崩溃。因此,出于某种原因,当我调用
[self.thinkOfViewController removeFromSuperview]
,应该立即将其删除

(旁注,textFlashViewController没有问题,唯一的问题是ThinkOfViewController)

这个范例是不是我设置了一个处理UiViewController输入和输出的糟糕实现?我已经读到了委托在这个例子中可以有所帮助,我只是不确定它是如何工作的


如果你们有任何想法,我将不胜感激,因为我已经通过论坛和文档挖掘,无法找到解决我处理这些观点的习惯性方法。

因此,简短的回答是肯定的,这是“范例”是处理UIViewControllers的一个糟糕的实现。我建议您阅读Apple的View Controller编程指南,其中概述了正确的实现,但这里有一个简短的概要:

从我收集的资料来看,您的MasterViewController管理着另外两个UIViewController,ThinkOfViewController和PicturePrimeViewController。当您在屏幕上添加或删除视图控制器的视图时,您不会将视图添加或删除到MasterViewController。视图控制器的全部功能是管理视图“显示”或“隐藏”其视图。我将“显示”和“隐藏”放在引号中,因为您没有实际显示或隐藏它们。您正在将它们从视图层次结构中推出,这是通过UINavigationController完成的。每个UIViewController都知道它所控制的UINavigationController(因此,UINavigationControllers被称为“控制器的控制器”),您可以这样将视图控制器推送到堆栈上

[self.navigationController pushViewController:vcToBePushed animated:YES];
当要删除堆栈顶部的视图控制器时,您只需说

[self.navigationController popViewControllerAnimated:YES];
将UIViewController推到堆栈上或从堆栈中弹出意味着视图控制器将其视图带到堆栈中,并在屏幕上显示或删除它。因此,最简单地说,这涵盖了UIViewController视图管理

另一个问题是关于EXC_BAD_access崩溃,这意味着您正在尝试访问已分配给另一个对象的内存。我怀疑罪魁祸首在这里:

if (randomNumber == 0) {

    self.flashTextViewIsDisplayed = NO;

    ThinkOfViewController *thinkVC = [[ThinkOfViewController alloc] initWithNibName:@"ThinkOfViewController" bundle:nil];

    self.thinkOfViewController = thinkVC;

    [thinkVC release];

    self.picturePrimeViewIsDisplayed = YES;
    [self.view addSubview:self.thinkOfViewController.view];        
}
问题是,在thinkVC有机会被MasterViewController的视图保留之前(在self.view addSubview:中发生),您就发布了thinkVC。因此,self.view将添加一个指向其内存刚刚添加回堆的对象的指针。取消我刚才概述的push/pop方法中的add/removeSubview方法将避免此类内存问题的发生


我希望这会有帮助,但让我们(这样做吧)知道您是否还有问题。

jmstone,感谢您查看我的长篇帖子!我尝试了一个导航控制器解决方案,但是这个应用程序在实现视图控制器方面有点奇怪,因此预期效果不起作用。但是,我做了一些更改,现在我取得了巨大的成功。非常感谢您抽出时间帮助我帮助我,也许没有它,我就没有现在的解决方案了!很高兴提供帮助。你说应用程序在实现视图控制器方面有点奇怪是什么意思?Max,我做了一个有许多嵌套视图控制器的项目。我使用了父子视图关系。我在这里的帖子中添加了解决方案代码,可能会有所帮助:-scott
-(void)handleSwipeFromRight:(UISwipeGestureRecognizer *)gestureRecognizer {
    if (!transitioning) {

        [self performTransition];

    }

}

-(void)performTransition {

    CATransition *transition = [CATransition animation];

    transition.duration = 1.0;

    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

    transition.type = kCATransitionPush;

    transition.subtype = kCATransitionFromLeft;

    transitioning = YES;

    transition.delegate = self;

    [self.view.layer addAnimation:transition forKey:nil];

    [UIView animateWithDuration:0.5 animations:^ {

        self.view.alpha = 0.0;

    }completion:^(BOOL finished) {

        NSLog(@"Transition Animation Complete");

    }];

}

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    transitioning = NO;

    [[NSNotificationCenter defaultCenter] postNotificationName:@"nextPrime" object:nil];

} 
-(void)nextPrime {

    if (self.picturePrimeViewIsDisplayed) {

        [self.picturePrimeViewController.view removeFromSuperview];

        self.picturePrimeViewController = nil;

        [self showAPrime];

    }

    if (self.flashTextViewIsDisplayed) {

        [self.flashTextPrimeViewController.view removeFromSuperview];

        self.flashTextPrimeViewController = nil;

        [self showAPrime];

    }

}
[self.navigationController pushViewController:vcToBePushed animated:YES];
[self.navigationController popViewControllerAnimated:YES];
if (randomNumber == 0) {

    self.flashTextViewIsDisplayed = NO;

    ThinkOfViewController *thinkVC = [[ThinkOfViewController alloc] initWithNibName:@"ThinkOfViewController" bundle:nil];

    self.thinkOfViewController = thinkVC;

    [thinkVC release];

    self.picturePrimeViewIsDisplayed = YES;
    [self.view addSubview:self.thinkOfViewController.view];        
}