首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

分段制造麻烦--新的视图控制器完全取代旧的VC

在软件开发中,特别是在iOS开发中,"分段制造麻烦"这个术语可能指的是在应用中切换视图控制器时遇到的一些问题。当一个新的视图控制器(VC)完全取代旧的VC时,可能会涉及到一些基础概念和潜在的问题。以下是一些相关的概念、优势、类型、应用场景以及可能出现的问题和解决方案。

基础概念

  • 视图控制器(ViewController):管理应用的用户界面和用户交互。
  • 导航控制器(Navigation Controller):用于管理一系列视图控制器的堆栈,提供前进和后退的功能。
  • 模态展示(Modal Presentation):一种临时显示视图控制器的方式,通常用于需要用户注意或完成特定任务的情况。

优势

  • 清晰的界面管理:每个视图控制器负责自己的界面和逻辑,便于维护和扩展。
  • 灵活的用户体验:可以通过不同的过渡动画和交互方式提升用户体验。
  • 资源管理:旧的视图控制器可以被释放,节省内存资源。

类型

  • 推入(Push):在导航控制器的堆栈中添加一个新的视图控制器。
  • 弹出(Pop):从导航控制器的堆栈中移除当前的视图控制器。
  • 模态展示(Modal):以覆盖的方式显示一个新的视图控制器。

应用场景

  • 应用启动时的主界面
  • 用户点击某个按钮后跳转到新的页面
  • 表单提交后的成功或失败提示页面

可能遇到的问题及原因

  1. 内存泄漏:旧的视图控制器没有被正确释放。
    • 原因:可能存在强引用循环,或者某些对象没有正确地设置为nil
    • 解决方案:确保所有强引用都被正确断开,使用弱引用来避免循环引用。
  • 界面跳转动画不流畅
    • 原因:复杂的视图层次结构或大量的计算任务阻塞了主线程。
    • 解决方案:优化视图层次结构,将耗时任务放到后台线程执行。
  • 数据状态丢失:新的视图控制器加载时,之前的状态信息丢失。
    • 原因:没有正确地传递或保存必要的数据。
    • 解决方案:使用协议、闭包或全局变量来传递数据,或者在视图控制器销毁前保存必要的状态。

示例代码

以下是一个简单的Swift示例,展示如何从一个导航控制器中推入一个新的视图控制器,并确保旧的视图控制器可以被正确释放:

代码语言:txt
复制
class FirstViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = UIButton(type: .system)
        button.setTitle("Go to Second VC", for: .normal)
        button.addTarget(self, action: #selector(goToSecondVC), for: .touchUpInside)
        view.addSubview(button)
    }
    
    @objc func goToSecondVC() {
        let secondVC = SecondViewController()
        navigationController?.pushViewController(secondVC, animated: true)
    }
}

class SecondViewController: UIViewController {
    deinit {
        print("SecondViewController is being deallocated")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let backButton = UIButton(type: .system)
        backButton.setTitle("Back", for: .normal)
        backButton.addTarget(self, action: #selector(backToFirstVC), for: .touchUpInside)
        view.addSubview(backButton)
    }
    
    @objc func backToFirstVC() {
        navigationController?.popViewController(animated: true)
    }
}

在这个示例中,当用户点击按钮时,FirstViewController会推入一个新的SecondViewController。当用户点击返回按钮时,SecondViewController会被弹出,并且会在控制台打印出“SecondViewController is being deallocated”,表明它已经被正确释放。

希望这些信息对你有所帮助!如果有更多具体的问题或需要进一步的解释,请随时提问。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

iOS 自定义分段控制器

最近做项目时遇到一些问题,就是项目里原有分段控制器的适用范围有些局限,虽然网上也有很多分段控制器的demo,但自己写的,可控性和项目适用性自己能很明白,所以我专门封装这样一个分段控制器,解决不同场景下的功能需求...首先,介绍一下分段控制器,相信大家也都见过这样的场景 ?...image.png 好,看到上图大家应该心里或多或少知道接下来要干的事了,我们一步一步分析如何封装一个好的分段控制器: 1.满足可配置多个子控制器 2.可配置菜单栏各个属性,如字体大小颜色等 3....); [self.pageScroll addSubview:vc.view]; } } 设置默认属性没什么好说的,创建子视图里有几点需要注意,一是标题按钮的创建,二是设置指示器的位置...,三是配置多个内容的控制器视图,仔细看代码,逻辑其实也很简单明了 4.实现按钮点击事件和视图滑动事件 #pragma mark - 事件 -(void)btnClick:(UIButton *)sender

1.3K31

iOS-UIWindow详解

iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的View,最后将控制器的View添加到UIWindow上,于是控制器的View就显示在屏幕上了。...一个iOS程序之所以能显示在屏幕上,完全是因为它有UIWindow,也就是说,没有UIWindow就看不到任何UI界面。 状态栏和键盘都是特殊的UIWindow。...系统在加载storyboard的时候会做以下三件事情 创建窗口 加载mian.storyboard 并实例化view controller 分配新视图控制器到窗口root viewcontroller...[self.window addsubview:rootVc.view];可直接将控制器的view添加到UIWindow中,并不理会它对应的控制器,但是这种方法违背了MVC原则,当我们需要处理一些业务逻辑的时候就很麻烦了...3.通过storyboard加载控制器 刚才我们提到过系统在加载storyboard的时候会做以下三件事情 创建窗口 加载mian.storyboard 并实例化view controller 分配新视图控制器到窗口

2K40
  • UI篇-VC的生命周期以及UIView的layoutSubviews和drawRect方法

    view完全显示 viewWillDisappear:控制器的view即将消失的时候 viewDidDisappear:控制器的view完全消失的时候 多个viewControllers跳转 当我们点击...viewDidAppear:ViewController2 完全出现 小结: 整个控制器声明周期: viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews...中了,而一个 VC 执行viewWillAppear 时必定是 self.navigationController 的 topViewController即栈顶的视图。...一个很常见的问题,我们需要在VC被销毁的时候处理一些事情,可是 viewWillDisappear 不管是入栈新的视图还是出栈当前视图都会被调用,无法判断,结合我之前说的原理,我们可以利用下面这个方法判断当前...但是在VC中,当前UIView的是在 viewDidLoad 执行后才初始化好的,所以我们会见到这样一个Bug,在VC初始化语句后面调用 一个 VC的绘制UI的方法,你会发现根本没有效果,这就是因为,VC

    1.9K30

    Swift 项目 - Xib | StoryBoard 多人协作技巧

    这样有利于视图样式和视图代码分离,有利于视图代码重用性和兼容性提高。 对于逻辑复杂的VC,应添加Object对象,并绑定相应的类来分离逻辑代码。...一个占位的容器视图指向子控制器的Embed Segue 按住Control键连线到想要包含的子控制器,占位视图的实例==子控制器的view(子控制器根视图) 选择Embed连线方式后,子控制器 的尺寸变化成跟占位视图一样的尺寸...---- 除此之外还可以使用Object对象 将它添加到控制器之上。 它的本质是一个继承自NSObject的子类,我们完全可以把它当成一个小功能模块的控制器。...,所谓的不容易测试,完全是因为重构不谨慎且对构造过程不理解,否则还是很容易定位问题且修改的。...但与之相对的是约束的概念较多,依赖人脑思考很容易产生遗漏,这样在运行的时候就会各种报错或显示异常,因此用纯代码写约束,反复运行调试视图样式尺寸十分常见,而且有些页面较深,测试起来十分麻烦。

    2.1K20

    编码篇-OC跨多层UI事件传递处理

    对于那种 subviews 特别多,事件又需要层层传递的层级视图特别好用,但是,缺点也很明显,必须依赖于 UIResponder 对象。...多层级View的UI事件处理有较好的方案,比如采用ReactiveCocoa、使用通知等等。可是ReactiveCocoa 的学习成本比较高,通知的话注册通知,发送通知也是比较麻烦。...场景 一个VC的View上放了很多的子视图,(中间有很多层)我们点击了最上面的一个Button,需要把Button的tag传到 VC中 Paste_Image.png 知识点( 此处不讨论代理回调和通知...view,控制器的view也没有重写父类方法, 于是将事件处理传递给控制器, 控制器重写了父类方法, 于是就走控制器重写的方法, 进行事件处理, 事件就成功地从button传到了控制器....值得注意的是,这样的事件传递处理方法,最常见的Bug就是当前试图初始化后确实存在,但是没有加载到父视图上,才导致的方法无法触发。 参考文章

    2.3K30

    iOS的MVC框架之控制层的构建(下)

    在这里面我想强调一点的是虽然控制器中拥有了一个view的根视图属性,但是控制器的生命周期一般要比根视图的生命周期要长,而且有可能会出现一个功能在不同场景下的视图呈现完全不一样,或者有可能会通过重新构建视图来实现一些换肤功能的场景...第一种方法本质上只是做了一些代码拆分,并未实现控制器和视图的完全分离;第二种方法则完全实现了视图和控制器之间的分离,视图的构建和布局不再依赖于控制器的存在,而且我们甚至可以对视图进行复用,也就是说可以让多个控制器类复用一个视图类中的代码...就如当功能中界面相同的两个视图控制器只是处理逻辑不相同,那么我们只需要派生出一个新的类并覆盖掉基类的处理逻辑方法即可。...} @end 基类里面的handleClick方法以及fn1方法都是专门用来处理VC1的逻辑和事件的,现在我们要构造一个VC1的派生类VC2,派生类中界面相同但是事件处理逻辑以及一些方法则完全不同。...我们还可以将这部分更新的逻辑提取出来让他即不在视图中处理也不在视图控制器中处理而是提供一个新的数据绑定类来解决这个问题。

    4.4K30

    iOS的MVC框架之控制层的构建(上)

    而且这种设计还有如下更多的考量: 视图界面千变万化,会根据用户的体验不停的升级和优化,甚至同一个功能的前后两个版本都有完全不同的差异,或者某些视图界面会分散到其他视图界面中去,又或原来分散的视图界面又聚合到某个新视图界面中来...也就是说视图呈现部分是变化最大以及持久性最短的一个部分。 模型(服务)则相对稳定,他只是提供了某些具体的基础业务服务,而且这些服务更多的是服务水平的升级而非服务的完全改变。...有些案例里面会出现每个VC的.h和.m文件都给他建立文件夹,其实这样不可取,因为有可能导致文件夹过多而变得查找定位更加麻烦。我们应该以相似的功能聚集在一起来建立文件夹进行管理。...self.vc.xxxx; //这里可以访问视图控制器的方法。 } @end .............................................self.vc.xxxx; //这里可以访问视图控制器的方法。

    1.6K20

    【YFMemoryLeakDetector】人人都能理解的 iOS 内存泄露检测工具类

    背景 即使到今天,iOS 应用的内存泄露检测,仍然是一个很重要的主题。我在一年前,项目中随手写过一个简单的工具类,当时的确解决了大问题。视图和控制器相关的内存泄露,几乎都不存在了。...我把旧代码适度拆分整理为一个开源库了,取名为 YFMemoryLeakDetector。本篇,将着重讲述简洁之下,可能不易察觉的一些考量。...*)[key pointerValue]; 对控制器和视图,采用不同的拦截策略 对象销毁,统一拦截的是 dealloc。...现在网上的很多策略,基本也是这样。 对象创建,对于视图,拦截的是 willMoveToSuperview: ;对于控制器拦截的是 viewDidLoad 。...vc.parentViewController) { /* 进一步过滤掉有父控制器的控制器. */ NSLog(@"有内存泄露风险的控制器: %@", obj); } }];

    1.3K60

    苹果全新UI框架来了!可视化编程,自动化减少20%代码量

    开发者通过SwiftUI,利用Swift语法就能够完成代码和设计的同步。 Swift是苹果最新的开发语言,有人呼吁谷歌取代TensorFlow的Python。目前在TOIBE排名18位: ?...一致性:这意味着Swift和Objective-C之间不会再看到奇怪的错误,或者非常旧的API与新API的混合 简洁:可以节省10%-20%的代码量 如果你刚刚接触SwiftUI,刚开始你可能需要适应一下...比如在使用源码控制时就很麻烦,会导致代码和可视化布局之间移动变得非常困难;使用动作和outlets时过于依赖flaky系统的连接。...而SwiftUI通过4种方式,解决了上述问题: 用一个新的声明式UI结构,定义了的布局的外观和工作方式 更新UI预览会自动生成新的Swift代码,反之,更改Swift代码也会更新UI预览 Swift中的任何绑定例如有效的...让Xcode for iPad更上一层楼 开发者对Interface Builder的抱怨不是一天两天了,它大大增加了分解视图块以及从视图控制器(view controller)使用视图的工作量,导致出现体积臃肿的视图控制器

    5.4K20

    VirtualCluster - 让k8s插上多租户的翅膀

    它通过为每个租户提供一个集群视图来扩展现有的基于命名空间的Kubernetes多租户模型. VirtualCluster完全利用了Kubernetes的可扩展性,并保留了完整的API兼容性....VirtualCluster由以下组件组成: •vc-manager:引入了新的CRD VirtualCluster对租户主机进行建模. vc-manager管理每个VirtualCluster自定义资源的生命周期...DaemonSet的工作负载.换句话说,如果规范中已设置其节点名,则同步器控制器将拒绝新创建的承租人Pod....建议将租户主节点控制器--node-monitor-grace-period参数增加到更大的值(> 60秒,已在示例clusterversion yaml中完成).同步器控制器不会更新租户主机中的节点租用对象...VirtualCluster使用自定义的coredns构建支持租户DNS服务.有关详细信息,请参见此文档. VirtualCluster完全支持租户服务帐户.

    1.3K30

    Cocoa编程中视图控制器与视图类详解

    使用pushViewController: animated:可推入一个新的控制器,从而增加新的项到导航栈。(记住:导航栏控制器不添加一个视图进去,这个导航栏是没有意义的!)...推入时,新的视图控制器从右方滑入屏幕(假定animated:YES)。向左指的Back后退按钮出现,可返回到上一步,且Back按钮用的是上一个视图控制器的标题。 2....在发送presentModalViewController: animated:消息后,一个新的视图控制器(其实是个ModalViewController)会滑动到屏幕并掌握控制权,直到使用dismissModalViewControllerAnimated...]; [controllers addObject:vc2]; */ // 将TabBar控制器的当前视图添加到窗口 [window addSubview:tabBarController.view...tabBarController:didSelectViewController: 是当用户选择一个新的选项卡时,控制器会发送这个消息。

    5.1K50

    快速入门

    概念 全称:Java Server Pages, Java服务端页面 描述:一种动态的网页技术,可以在其中定义HTML、JS、CSS等静态内容,以及Java代码的动态内容 说明:JSP = HTML...%>标签是可以分段的,这样写,只是为了让我们更直观的知道get后值赋给谁 JSP 缺点 ---- 由于JSP页面内,既可以定义 HTML 标签,又可以定义 Java代码,造成了以下问题: 1.书写麻烦...;特别是复杂的页面 2.阅读麻烦 3.复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE... 4.占用空间和磁盘:JSP会自动生成 .java 和 .class文件占用磁盘,运行的是...el表达式获取数据,会依次从这4个域中寻找,知道找到为止 JSTL 标签 ---- 全称:JSP标准标签库(Jsp Standard Tag Library),使用标签取代JSP页面上的Java...,视图,界面展示 Controller,控制器,处理请求,调用模型和视图 MVC 好处 职责单一,互补影响 有利于分工协助 有利于组件重用 类似于三层架构

    1K20

    【百度】一面总结(含答案)

    1.3.2 main 阶段 梳理各个二方/三方库,找到可以延迟加载的库,做延迟加载处理,比如放到首页控制器或 tabBar 控制器的 viewDidAppear 方法里,并且保证只执行一次(按项目结构...避免在用户看到的第一个界面(首页控制器或注册登录页面)的 viewDidLoad 和 viewWillAppear 做太多事情,这 2 个方法执行完,第一个页面才能显示,部分可以延迟创建的视图应做延迟创建...,并把重置 HEAD 所带来的新的差异放进暂存区reset --soft 会在重置 HEAD 和 branch 时,保留工作目录和暂存区中的内容,并把重置 HEAD 所带来的新的差异放进暂存区。...它的行为是:保留工作目录,并且清空暂存区。也就是说,工作目录的修改、暂存区的内容以及由 reset 所导致的新的文件差异,都会被放进工作目录。...当你在 reset 后面加了 --hard 参数时,你的 stage 区和工作目录里的内容会被完全重置为和 HEAD 的新位置相同的内容。换句话说,就是你的没有 commit 的修改会被全部擦掉。

    52630

    iOS-控制器View的创建和生命周期

    控制器View的创建 首先我们来看一下控制器view创建的流程图 控制器view加载.jpeg 从图中我们可以看出,在控制器view加载过程中有两个重要的方法loadView和viewDidLoad。...viewDidLoad 作用:一般我们会在这里做界面上的初始化操作,比如往view中添加一些子视图等。 什么时候调用:每当view创建完毕的时候,最终都会调用viewDidLoad方法。...: 控制器的view布局子控件完成 viewDidAppear: 控制器的view完全显示 viewWillDisappear: 控制器的view即将消失的时候...viewDidDisappear: 控制器的view完全消失的时候 view生命周期方法调用顺序 viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews...ViewController *vc = [[ViewController alloc] init]; vc.view.backgroundColor = [UIColor

    1.4K60

    跟iOS UI的捉迷藏,真的能够获取到self.presentingViewController

    关于第一点,很重要,意思是说父VC和自身都可以调用dismiss,系统会自动去找presenting的控制器 关于第二点,如果业务十分复杂,present了很多控制器,想一下子回到栈顶的控制器,则可以...,如果当前执行的控制器不是一个全屏的控制器,它将在视图层级结构中找到一个全屏的父类控制器去执行present事件。...这就会影响self.presentingViewController获取,有时业务要求还是需要获取代码上presentVC的控制器 那么能不能把这个变量确定呢 解决这个需求,我们需要用到一对属性 @property...会使用视图层级内的这个控制器来进行跳转。...,第二个控制器加载成功,但同时会有一个新的warning:Presenting view controllers on detached view controllers is discouraged

    74120

    VC++6.0重命名Project名称及其MFC工程及类文件名

    VC++6.0重命名MFC工程及类文件 经过本人亲自测试,修改Project名称完全正确,非常感谢原作者的辛勤劳动成果,特此感谢!...也特地转载与大家一起分享 ^_^ 修改时建议直接用“替换”批量修改,以防遗漏修改的地方,比较麻烦。...总之完全按照下面的步骤,一定能修改成功的,我亲测鉴证过 呵呵       作为MFC新手使用VC++6.0这古董级的东西有时实在痛苦,这有空几天都在想怎么重命名MFC工程的命名空间和类文件。...如果要修改命名空间,那么把所有命名空间命名的文件都改为新的,包括Resources文件夹里面以旧命名空间命名的文件,不需要就不要改了。 3.修改工程信息。       ...笔记本打开,使用Crtl+F找出旧命名空间并改为新的,主要是修改.rc2和.ico的旧文件名。因为我们在Resources文件夹里面将他们重命名了。       (3).修改dsp文件。

    1.7K20

    Swift-MVVM 简单演练(一)

    创建视图控制器 let vc = cls.init() vc.title = title // 3....如果不想对原方法有改动,那么就要重新写一个完全一样的只是最后面增加了这个需要的参数而已的一个新的方法。 你看swift是不是真的简洁了许多。...到目前为止,虽然我们只是在基类控制器里面创建了访客视图setupVistorView,只有一个访客视图的HQVistorView,但是实际上当我们点击不同的子控制器的时候,每个子控制器都会创建一个访客视图...创建视图控制器 let vc = cls.init() vc.title = title vc.visitorInfoDictionary = vistorDict } 将数组写入...总结 使用代理传递消息是为了在控制器和视图之间解耦,让视图能够被多个控制器复用,如TableView 但是,如果视图仅仅是为了封装代码,而从控制器中剥离出来的,并且能够确认该视图不会被其它控制器引用,

    10.3K51
    领券