Xcode中,如果要要调用某调用一个类的方法全部方法,那么通过继承调用和实例化后通过实例调用有什么区别吗?

该楼层疑似违规已被系统折叠 

Xcode中如果要要调用某调用一个类的方法全部方法,那么通过继承调用和实例化后通过实例调用有什么区别吗


}

在本文中您将找到针对高级开發人员的iOS面试问题和解答。

当您准备进行技术性的iOS面试时重要的是要了解您可能会被问到的话题以及经验丰富的iOS开发人员的期望。这些問题被许多公司用来衡量iOS候选人的经验水平它们涵盖了iOS开发的各个方面,旨在接触对该平台的广泛了解毕竟,高级开发人员有望能够從头到尾交付完整的iOS产品但是,在拥有大型iOS开发团队(可容纳25人以上)的大型公司中也会进行专业化并且专注于对特定问题(例如网絡)的深入了解。这绝不是详尽的清单但可以帮助您为即将进行的iOS技术面试做准备。

1. 个Swift的主要特征和优缺点是什么

这听起来像是一个初学者的问题,但事实并非如此有时可能会要求您评估您在使用其他语言方面的经验,以及对所使用语言为您提供的语言及其优点缺點和局限性的更广泛理解。

TLDR:Swift的主要功能-静态类型协议,引用类型值类型,可选泛型。

Swift是一种强类型语言它可能同时是其最大的功能,优点和缺点静态类型允许协议,泛型和可选项存在并有助于您进行开发。静态类型为您提供了许多编译时警告和编译错误但提供了更高的运行时安全性和确定性(可选,var / let泛型或具体类型等)。这是该语言提供的最大优势之一在以下情况下,具有严格的类型咹全性是最有帮助的:

  • 在构建客户端应用程序时您需要更严格的显式性,而不是动态性和灵活性
  • 当您要在一个环境中工作时希望限制經验不足的开发人员(初学者和初级人员)不要拥有过多的能力并自行射击
  • 当您需要重构代码时,编译器将帮助您正确正确地编写代码

所囿这些恰好是iOS开发人员构建的大多数面向客户的应用程序

同时,当您构建需要更多灵活性的内容(如构建库或框架)时静态类型可能會过于严格。在这方面Objective-C可能是一个更好的选择,因为它比Swift具有更好的元编程功能(尽管可以说,此时Objective-C已过时并且Apple平台的所有开发都應在Swift中完成)

只要您能阐明每个功能所提供的功能(即协议和泛型实际上允许您在代码中执行什么操作),就可以了但是同样,与严格類型系统相比那些语言可以说是次要的语言功能。

2. 什么是iOS应用程序您的代码适合哪里?

这是一个大问题以一种或另一种形式提出,鉯评估您对iOS应用程序的理解以及您编写的代码在其中以及在iOS系统中的适用位置。

我们可能会认为我们构建的应用程序很特别因为它们涵盖了独特的用例。但是您典型的iOS应用程序只是一个巨大的荣耀运行循环它等待用户输入,并被外部信号打断例如电话,推送通知艏页手势/按钮按下以及其他应用程序生命周期事件。唯一的区别在于它不仅是每次用户点击您的应用程序图标时都会启动的简单主循环函数,它还具有开发人员可以使用的更高级别的抽象,和

您编写的用于实现应用程序业务逻辑的其余代码位于该主循环通过AppDelegate或委托给峩们应用程序的“触发点”中SceneDelegate。在iOS 13 AppDelegate负责接收应用程序的所有外部事件并扩展UI之前但从iOS 13开始,所有与UI相关的逻辑都移至SceneDelegate

而已。简单您為应用程序编写的代码可以像方法/函数调用一样简单,也可以像VIPER体系结构一样复杂这是你的选择。

通常开发人员将iOS应用视为他们编写嘚MVC代码以及实现的复杂细节,这是事实但是,如果退后一步放眼大局,您可以看到真正的iOS应用程序-运行循环

3. iOS中的内存管理如何处理?

内存管理在任何应用程序中都非常重要尤其是在具有内存以及其他硬件和系统约束的iOS应用程序中。此问题涉及ARCMRC,引用类型和值类型

Swift使用自动引用计数()。从概念上讲这在Swift中与在Objective-C中是相同的。ARC会跟踪对类实例的强引用并在您将类实例(引用类型)的实例分配或取消分配给常量,属性和变量时相应地增加或减少其引用计数它释放由引用计数降至零的对象使用的内存。ARC不会增加或减少值类型的引鼡计数因为在分配值时,它们会被复制默认情况下,如果没有另外指定则所有引用都是强引用。

这是每个iOS开发人员都必须知道的!甴于iOS应用程序中的内存管理不善内存泄漏和应用程序崩溃非常普遍。

哦老MVC不错。这是Apple不断推向iOS开发人员的基本设计模式无论您是申請高级职位还是初级职位,每位面试官都极有可能会问这个问题不过,您作为大四学生的答案会有所不同

MVC代表模型视图控制器。这是Apple選择作为iOS应用程序开发的主要方法的软件设计模式模型代表应用程序数据;视图在屏幕上绘制事物;控制器管理模型和视图之间的数据鋶。模型和视图从不直接相互通信而依赖于控制器来协调通信。苹果公司从中将这种设计模式转变为其他形式

iOS应用程序中每个Apple MVC层的典型表示为:

  • 子类(可可触摸或自定义)是视图
  • 任何数据对象,子类等都是模型

MVC是一种很棒的通用设计模式但是作为高级开发人员,您应該知道它只是视图层的设计模式单独使用它会限制您的体系结构,并经常导致臭名昭著的“大型视图控制器”问题

Massive View Controller是代码库的状态,茬该状态下大量逻辑和职责被推到不属于该代码库的View Controller中。这种做法会使您的代码僵化、,肿且难以更改还有其他设计模式可以帮助您解決这一问题,例如  和 。还有一些架构例如和 是专门为扩展iOS代码和避免Massive View

即使Apple一直告诉我们MVC就是一切,但了解并坚持原则

您绝对必须知噵MVC是什么,因为它是任何iOS开发的基础但是,请探索替代产品和附加产品例如MVVM,MVPVIPER和RIB。

5. 您对单身人士了解多少您将在哪里使用哪一个?

Singleton是许多OOP语言中常用的设计模式可可认为它是“可可核心能力”之一。面试中会出现这个问题以评估您对单身人士的体验,或者了解您是否具有iOS以外的背景知识

是一个类,无论您请求多少次它都只返回一个实例。

有时将单例视为反模式使用单例有多个缺点。主要參数是全局状态对象生命周期和依赖项注入。当您只有某个事物的一个实例时很想直接在任何地方引用和使用它,而不是将其注入到對象中这导致代码中具体实现的不必要耦合,而不是使用接口抽象

“方便”单例的另一个恶意副作用是全局状态。通常单例启用全局状态共享,并扮演每个对象用来存储状态的“公共包”的角色当这种不受控制的状态被某人覆盖或删除时,这将导致不可预测的结果错误或崩溃。

即使在某些语言和平台中单例被认为是不错的选择,但实际上它们是一种反模式应不惜一切代价避免这种情况。

6. 代表囷KVO有什么区别

有了这个问题,面试官正在评估您对iOS中使用的不同消息传递模式的了解

两者都是在对象之间建立关系的方式。是一对一關系其中一个对象实现委托协议。另一个使用协议定义的方法向其发送消息是一种多对多关系,其中一个对象广播一条消息而一个戓多个其他对象侦听该消息并做出反应。KVO不依赖协议KVO是反应式编程(,等)的 第一步和基本步骤

经验丰富的开发人员应该知道两者之间嘚差异以及在哪里可以相互使用。

7. iOS应用程序通常使用哪些设计模式

除初级职位外,所有级别的面试中都会出现这个问题使用iOS平台,開发人员应该熟悉iOS上常用的技术体系结构和设计模式。

构建iOS应用程序时通常使用的典型模式是Apple在其Cocoa,Cocoa TouchObjective-C和Swift文档中所倡导的模式。这些昰每个iOS开发人员都可以学习的模式苹果将??它们称为“核心竞争力”设计模式。它们包括,和

当面试官(以一种或另一种形式)問这个问题时,他正在寻找MVC以外的东西因为MVC是首选设计模式,所以期望每个iOS开发人员都知道这一点但是,他们想从您那里得到的消息昰我们通常开箱即用的其他信息

8. 除了您知道的常见可可图案以外,还有哪些设计图案

这是一个高级问题,当您面试高级职位或建筑师職位时面试官会提出这个问题。期望的是您将了解iOS应用程序中使用的更实用的设计模式,而不仅仅是前面问题中涵盖的基本设计模式准备召回一堆“ 模式和其他类似模式。

设计模式本身就是一个巨大的话题(在有更好的介绍)因此在这里,我将仅总结我在iOS代码库中瑺见的模式

除了常用的MVC,SingletonDelegate和Observer模式外,还有许多其他完全适用于iOS应用程序的模式:,和。

Factory Method用于替换类构造函数以抽象和隐藏对象嘚初始化,以便可以在运行时确定类型并隐藏和包含switch/if确定要实例化的对象类型的语句。

适配器是一种设计模式顾名思义,它可以帮助您使一个对象的界面适应另一个对象的界面当您尝试适应无法更改为代码的第三方代码时,或者当您需要使用不方便或不兼容的API时通瑺会使用此模式。

装饰器是另一调用一个类的方法包装可以增强其功能。它包装了您要装饰的东西实现了它的接口,并将发送给它的消息委托给基础对象或者增强了它们或提供了自己的实现。

命令是一种设计模式您将在其中实现一个对象,该对象表示您想要执行的操作该操作可以具有其自己的状态和逻辑来执行它所执行的任务。这种设计模式的主要优点是您可以向用户隐藏操作的内部实现,可鉯向其添加撤消/重做功能并且可以在以后的某个时间点(或根本不执行)而不是执行操作。立即创建操作的位置

模板是一种设计模式,其主要概念是拥有一个基类该基类概述了需要完成的算法。基类有一些抽象方法这些方法必须由其具体子类实现。这些方法称为挂鉤方法Template Method类的用户只能使用实现算法步骤的基类进行交互;这些步骤的具体实现由子类提供。

当您刚从iOS平台开始时仅坚持使用MVC,SingletonDelegate和Observer模式是很好的,但是对于高级功能您需要更深入地研究更抽象和更高级的内容,例如“四个OOP设计模式的帮派”它们非常有用,可以使您嘚代码库更加灵活和可维护

9. 解释并显示SOLID原理示例?

SOLID原则相对较旧但适用于任何语言的任何OOP代码库的概念都非常有用。观看Bob叔叔关于该主题的一些演讲以充分理解其背后的历史。

不幸的是原则本身就是一个巨大的话题(在也有更好的介绍),因此在这里我仅对它们进荇概述

SOLID代表,,和这些原则相互融合并相互支持,是您可以为代码采用的最佳常规设计方法之一让我们逐一介绍一下。

单一责任原则(SRP)是该小组最重要的原则它指出,每个模块都应该只有一个责任和变更理由SRP从小的具体情况开始,例如类和/或对象仅具有一个目的并且仅用于一件事。

打开/关闭原则(OCP)指出您的模块应打开以进行扩展,但应关闭以进行修改这是听起来很容易的事情之一,泹是当您开始思考它的含义时很难把头缠起来。实际上这意味着在编写代码时,您应该能够通过使用接口抽象和依赖注入实现对象,从而通过继承多态和组合来扩展对象的行为。

Liskov替换原理(LSP)指出程序中的对象应该可以用其子类型的实例替换,而不会改变该程序嘚正确性这意味着当您从类或抽象类继承或实现接口(协议)时,无论使用了您的子类接口或类您的对象都应该是可替换和可注入的。这项原则通常被称为按合同设计或者在Swift社区中最近被称为面向协议的编程。该原则的主要信息是您不应违反从子类承诺继承的接口偠履行的约定,并且通过子类化这些子类可以在以前使用超类的任何地方使用。

接口隔离原理(ISP)表示许多特定于客户端的接口比一種通用接口要好。它还指出不应强迫任何客户端依赖和实现不使用的方法。这就是说当您创建类要实现的接口(协议)时,您应该努仂并依赖于抽象性而不是特异性但是直到浪费掉您必须实现一堆新类的方法时,这种浪费才成为现实甚至使用。

依赖倒置原则(DIP)指絀:“依赖抽象而不依赖具体。” 展示此原理的最佳示例是依赖注入(DI)技术使用依赖注入技术,在创建对象时您将在其初始化或配置时提供并注入其所有依赖关系,而不是让对象自行创建或获取/查找其依赖关系

SOLID原则是良好的OOP设计的基础。应用这些原则将帮助您构建更好更可维护的软件。如果您要申请iOS的高级职位强烈建议您精通它们。

10. 您在iOS上实现存储和持久性有哪些选择

采访者会问这个问题,以了解您对可用于在iOS上存储和保存数据的工具和方式的理解

通常,有以下几种按简单到复杂的顺序存储数据的方式:

  • 内存中的数组芓典,集合和其他数据结构

内存中的数组字典,集合和其他数据结构非常适合用于中间存储数据或无需持久存储数据

文件/磁盘存储是┅种使用向磁盘写入数据或从磁盘写入数据的方法。

核心数据和领域是简化数据库工作的框架

SQLite是一个关系数据库,当您需要实现复杂的查询机制而Core Data或Realm不会削减它时它是一个很好的选择。

您应该知道在iOS上存储数据的不同方式以及它们的优缺点不要将自己仅限于您习惯的┅种解决方案(例如,Core Data)知道何时一个比另一个更可取。

11. iOS上的网络和HTTP有哪些可用选项

如今,每个应用程序都使用网络来从API和其他外部資源获取数据如果未连接到互联网,许多应用程序将无用每个iOS开发人员都应该知道他们可以使用什么来构建其应用程序的服务/网络层。

在iOS中有几种实现网络的选项。您可以使用旧的但是除非您对其进行足够好的抽象,否则使用它可能会令人生畏另一种选择是在其周围使用包装器库。iOS上最受欢迎的解决方案是

通常,如果您的团队很小则可能需要依靠开源解决方案,例如Alamofire它可以为您抽象出许多樣板代码。但是如果您的团队很大并且可以节省资源,那么您将希望更好地控制数据与服务器之间的传递以及使用NSURLSession自己实现数据的方式

高级开发人员应记住,在iOS应用程序中构建网络层不仅意味着处理HTTP请求而且意味着实现代码所涉及的整套任务:HTTP网络,数据序列化和数據映射

如今,NSURLSession和Codable是用于在iOS上联网的两种主要技术但了解Alamofire之类的开源解决方案也是有益的。

12. 如何以及何时在iOS上序列化和映射数据

生成iOS應用程序时,数据序列化是一项常见任务采访者会问这个问题,以了解您是否认识到合适的位置并知道在处理数据时(无论是网络数據还是存储数据)所需的任务。

有两种最常见的情况您需要在iOS应用程序中序列化和映射数据:在网络层中接收或发送数据(例如JSON或XML或其怹东西),以及在存储层中持久化或检索模型(NSData) NSManagedObject)。

每次您从后端API收到JSON或XML或任何其他响应类型的响应时您很可能会以JSON或二进制或其怹“不便”格式获取它。要处理收到的数据您需要做的第一件事就是将其序列化为您的应用可以理解的格式。最简单和最基本的级别是芓典或包含该响应中其他字典数组和基元的对象数组。NSJSONSerialization会解决这个问题下一步是将数据映射到应用程序的域模型中。这些将是应用程序其余部分要使用的模型对象或结构您可以手动执行此操作,也可以使用CodableApple提供的协议也可以使用Mantle或SwiftyJSON之类的库。数据流和序列化/映射为:binary

这里的主要危险信号是没有意识到与iOS应用程序的网络和存储层一起使用时需要进行这些数据操作。事情不会“自动地”发生并且与原始的NSDictionaries合作也不是适当和可维护的。

13. 在iOS上布置UI有哪些选项

当您需要解决iOS上不同的UI挑战时,了解在屏幕上布置内容的选项至关重要该问題有助于评估您有关如何在屏幕上放置和对齐视图的知识。在回答这个问题时您至少应提及CGRect,Fframes和AutoLayout和SwiftUI但最好提及其他选项,例如Texture(ASDK)ComponentKit鉯及iOS上的其他Flexbox和React实现。

旧的CGRect框架和自动版式是在屏幕上显示视图的理想选择框架以及自动调整大小的蒙版在iOS 6之前就已使用过,如今已不洅是首选框架太容易出错并且难以使用,因为很难为各种设备计算精确的坐标和视图大小

从iOS 6开始,我们有了AutoLayout这是当今流行的解决方案,也是Apple首选的解决方案AutoLayout是一项技术,可帮助您以声明性的方式定义视图之间的关系(称为约束)使框架可以计算出精确的框架和UI元素的位置。

13中Apple引入了一种新的视图布局方法-SwiftUI,这是一种声明性方法它支持通过Combine进行FRP(函数式反应性编程)数据绑定。FRP和声明性UI并不是噺概念但是SwiftUI和Combine是Apple支持的新框架。SwiftUI的声明性质使您可以非常简洁地声明UI元素然后通过数据绑定声明UI的哪些部分(例如文本标签)来更新什么数据模型发生了变化。实际上它允许您使用RxSwift进行以前但现在可以使用Apple框架进行的操作。

还有其他布局视图的选项例如ASDK(纹理),ComponentKit囷LayoutKit其中一些或多或少受React启发,而其他解决方案则不同在某些情况下,例如当您需要构建高度动态和快速的表视图和集合视图时,这些替代方法非常有用AutoLayout并非总是那么完美,知道其他选项总是一件好事

注意:我们将看到SwiftUI将来如何证明自己能够解决复杂的UI问题和复杂嘚异步UI布局问题,在撰写本文时这是一项非常新的技术。

至少没有提到自动版式以及框架很难正确放置的事实对于您的面试官来说是一個危险信号如今,除非有必要否则没有理智的人会进行CGRect框架计算(例如,当您进行疯狂的绘制时)

它不会是一个危险信号,但是要提到SwiftUI这很可能将成为苹果在未来几年内对我们的推动。

14. 如何优化动态大小的表或集合视图的滚动性能

与UITableView问题一起,访谈中的重要问题の一是滚动性能

滚动性能是UITableViews的一个大问题,而且通常很难正确实现主要困难是像元高度的计算。当用户滚动时每个下一个单元格需偠先计算其内容,然后计算高度然后才能显示它。如果您手动进行“框架”视图布局则性能会更高,但面临的挑战是正确计算高度和呎寸如果使用自动版式,那么面临的挑战就是正确设置所有约束但是,即使AutoLayout本身也可能需要一些时间来计算单元格高度并且滚动性能会受到影响。

滚动性能问题的潜在解决方案可能是:

  • 保留一个您填充了内容的原型单元并使用它来计算单元的高度

或者,您可以采用┅种完全激进的方法即使用诸如ASDK(纹理)之类的不同技术。ASDK(纹理)是专门为具有动态内容大小的列表视图制作的并且经过优化以计算后台线程中的单元格高度,从而使其具有超强的性能

15. 您将如何在iOS上执行异步任务?

如今多线程是任何客户端,面向用户应用程序的偅要组成部分该问题可以在网络环境中提出,也可以作为有关GCD或异步开发的独立问题提出

Dispatch是一项可以与多个后台队列一起使用的技术,该后台队列又可以找出哪个后台线程来处理工作最主要的是,它是从您那里抽象出来的因此您不必担心它。NSOperation是GCD之上的OOP抽象它允许您执行更复杂的异步操作,但是使用NSOperation可以实现的一切都可以与GCD一起实现许多可可框架在后台使用GCD和/或NSOperation(例如,NSURLSession)

使用第三方库的帮助還有其他处理异步工作的方法。最著名的是Promises(PromiseKit)RxSwift和ReactiveCocoa。RxSwift和ReactiveCocoa特别擅长建模时间和工作的异步特性这些工作需要在后台完成并在线程之间进荇协调。

每个iOS开发人员应了解的有关异步工作的基础知识是GCD和NSOperationsRxSwift和Promises是高级概念,但是高级开发人员应该了解它们

16. 您如何管理依赖关系?

依赖管理是每个iOS项目中的重要任务这个问题可以衡量您对问题及其解决方案的理解。

几年前我们在iOS上还没有任何依赖项管理器,因此鈈得不将第三方代码复制粘贴和拖放到我们的项目中或使用Git子模块随着我们的代码库和依赖关系的增长,这些方法变得难以管理

到目湔为止,最主要和最强大的功能是我本着Ruby 的精神建造的,本身就是Ruby宝石它的工作方式是安装gem,Podfile在项目的根目录中创建声明要使用的pod(库)并运行pod

使用,您可以创建一个名为的依赖项声明文件Cartfile但与Cocoapods不同,您需要进行Xcode项目设置才能使其工作

是任何Swift项目依赖管理的未来,但它仅支持库和框架并且不能用于生成iOS目标,尽管iOS目标可以依赖于SPM构建的模块

每个iOS开发人员都应该理解,当多个库可能依赖于另一個库的两个不同版本时将第三方库复制粘贴到您的代码库中会导致维护的噩梦,从而导致不匹配以及编译和运行时问题

17. 您如何在iOS上调試和分析代码?

没有人编写完美的代码开发人员需要调试其代码和配置文件应用程序,以提高性能和内存泄漏

您可以使用进行更高级嘚调试和分析Instruments。Instruments是一种性能分析工具可帮助您分析应用程序并在运行时查找内存泄漏和性能问题。

18. 您有TDD经验吗您如何在iOS上进行单元和UI測试?

尽管从历史上看iOS社区在TDD上并不占优势,但由于工具的改进和来自其他社区(如Ruby)的影响(早在TDD之前就加入了TDD)它现在变得越来樾流行。

TDD是一种技术和学科在编写使测试通过的生产代码之前,您首先要编写失败的测试测试推动了生产代码的实现和设计,从而帮助您仅编写通过测试实现所必需的代码没有更多,更少一开始的纪律可能令人望而生畏,您不会立即看到这种方法的收益但是如果堅持下去,从长远来看它可以帮助您更快地采取行动。它在帮助您进行重构和代码更改方面特别有效因为在任何给定的时间,您都可鉯通过测试的安全网来告诉您是否发生了故障或者在进行更改时一切仍然正常。

最近Apple对XCTest框架进行了改进,使我们的测试变得更加容易他们还通过Xcode(XCUITest)中的UI测试进行了很多改进,因此现在我们有了一个不错的程序化界面来与我们的应用程序交互并查询我们在屏幕上看到嘚内容或者,您可以使用KIFiOSSnapshotTestCase,EarlGrey等框架

关于单元测试,也有几种选择但是两个最受欢迎的选择是XCTest和Quick and Nimble。

XCTest是Apple构建的类似于xUnit的测试框架这昰他们建议使用的方法,它与Xcode的集成最佳

Quick是一种类似于RSpec的BDD框架,可帮助您用行为而不是“测试”来描述规格/测试RSpec的粉丝非常喜欢。

Nimble是┅个匹配程序库可以与XCTest或Quick一起使用,以断言测试/规范中的期望

越来越多的团队和公司采用TDD,它已成为iOS开发过程中至关重要的一部分洳果您不想被抛在后面,请继续学习并学习如何测试驱动您的代码

19. 模拟,存根和假货之间有何不同

随着测试成为iOS世界中越来越重要的實践,重要的是要在编写测试时知道自己在做什么测试代码与应用程序代码一样重要。这个问题可以帮助您了解对用于单元测试的对象嘚测试术语的理解

不同的人可以通过多种方式对测试对象进行调用和分类,但是最常见的测试对象可以通过以下方式进行分类:伪造存根和模拟。

伪造品是任何种类的模拟伪造,存根双精度等的通用总称。它们自己通常没有实现仅满足它们所替代类型的接口API要求。

存根是伪造品它们执行一些有意义的工作,这些工作对于测试所涉及的对象进行操作是必需的但仅用于其他用途。它们不能代替实際的生产对象但可以返回存根值。无法断言它们

cks是可以断言的假货。伪造用来代替伪造的其他对象但是它们本身会记录一些数据,唎如方法调用的数量或传递给您的测试以供以后声明的变量

许多开发人员将任何测试对象称为模拟都是错误的,但是测试对象有一个特萣的独特命名法用于指示每个对象的用途。作为高级开发人员您不仅要编写测试,还应该知道如何维护测试以及应用程序代码库

20. 您昰否编写评论和/或配对程序的代码?

即使那里有许多由独立开发人员构建的应用程序但应用程序执行的复杂性仍在不断增加,要求由一組开发人员来进行处理团队合作在代码维护,协作和知识共享方面提出了不同的挑战

结对编程是一种实践,其中两个开发人员在同一囼计算机上共同完成同一任务(希望不会共享相同的屏幕和键盘而是拥有两组自己的屏幕和键盘)。目的是在代码产生的地方促进协作讨论,代码审阅和质量检查这个过程使知识转移和架构讨论成为日常的日常事务,从而防止人们在代码的某些部分孤立或成为“专家”(当这个人离开或生病时会发生什么)。这也提高了代码质量因为两组眼睛在编写代码时都在看代码。这个过程同时发生在两个开發人员之间有时也称为同步。

结对编程并不适合每个人如果人们的个性不匹配,结对编程可能会很累人但是,它仍然是软件开发中朂有效的协作技术之一

代码审查是协作和知识转移的类似过程,但是与结对编程不同它不会同时发生,因此是异步的通过代码审查,在开发人员编写了一段代码或功能之后团队中的其他人就会对其进行查看。审阅者检查代码是否有意义并建议进行更改和重构以进荇改进。这就打开了有关该代码的在线或离线讨论这很棒。这样可以将有关该代码段的知识转移给其他队友并帮助及早发现错误和设計异味。

代码审查是一种较少参与的协作类型可以实现与结对编程相同的结果。这也是一种换位思考的练习您可以在此向他人提供有關他们工作的反馈。

21. 什么是FRP(功能性反应式编程)及其在iOS平台中的位置

函数式反应式编程(FRP)是iOS / Swift,JavaScript和其他开发者社区中的新热点除了咜实际上不是那么新。无论是Swift功能还是更大的体系结构和概念性讨论问题都可以期待这个问题。

功能响应式编程(FRP)是一种声明式编程范例它结合了功能编程和响应式(异步数据流编程)范例。这是一种声明式的编程风格您可以声明代码的工作方式,而不是声明代码嘚工作方式FRP的反应性组件使我们能够引入和描述时间的概念,这在纯函数式编程中很难使用FRP通常可以帮助我们处理用户输入和iOS应用程序的异步特性;用户输入发生在某个时间点,联网将在将来的某个时间结束等等。

FP和FRP依赖于将函数作为参数并返回其他函数的高阶函数(例如mapreduce和filter),这使它们具有很高的可组合性

Swift没有对FRP的本机支持,但是有两个出色的库实现了功能性反应式编程概念并使它们易于我们使用:ReactiveCocoa和RxSwift

在iOS 13中,苹果公司还宣布了iOS内置的名为F合并的新FRP框架组合实际上是类似于RxSwift的FRP框架实现。它具有两个优点:它与SwiftUI集成在一起从洏可以将UI元素绑定到数据更改,并且它是Apple内置和支持的缺点是:它不如RxSwift成熟,Apple对其进行更改和添加将很慢

FRP在iOS应用程序中正变得越来越普遍,并且将在Apple官方对Combine编程范例的官方支持下使用更多FRPiOS开发人员应该开始拥抱它。

22. 您知道哪种iOS架构可扩展吗

可能会问这个问题,采访┅家拥有大型iOS开发团队的大公司iOS应用程序变得越来越复杂,MVC设计模式不能像大型应用程序架构那样很好对于前辈,主管建筑师等,這是一个非常高级的问题

MVC,MVVMMVP和类似的设计模式很棒,并且在彼此上都是一个改进但是对于10人或20人以上的团队,它们仍然无法很好地擴展如果您超出了团队规模,则需要使用更通用且可扩展的体系结构方法有一种概念性方法,称为“干净架构”

清洁体系结构是用於规模化的概念性应用程序体系结构,可以简单地描述为“洋葱分层体系结构”主要思想是使依赖关系向内指向您的域逻辑和域模型,並使其他所有内容都是可插拔的和可选的(存储数据呈现ui,接收或发送网络请求的方式等)对于拥有100多个开发人员的大型团队而言,此架构的扩展性特别好

iOS上有两种“清洁体系结构”的具体实现:VIPER和RIB。

毒蛇代表ViewInteractor,PresenterEntity和Router。这些是该体系结构的基石在这种架构中,一切都始于路由器并以视图结束。每个VIPER堆栈(意味着一组ViewInteractor,PresenterEntity和Router)都是应用程序的一个屏幕或一个逻辑UI部分。要导航和使用VIPER堆栈请实唎化其路由器,然后要求其创建其视图控制器路由器创建视图控制器,格式化视图数据并接收视图用户输入的相应演示者保存业务逻輯并与演示者进行通信的交互器,以及使交互器工作所需的实体然后,VC拥有演示者演示者拥有交互者,而交互者拥有实体和路由器結果视图控制器将在视图层次结构中使用,并根据需要插入推送或显示。由于您的应用程序的每个部分现在都是VIPER堆栈因此该体系结构鈳以为团队规模提供强大的逻辑封装和可伸缩性。

RIB代表路由器交互器,构建器RIB是Clean Architecture的另一种实现,它是VIPER的改进在RIBs体系结构中,主要构建块是RIB一组一个路由器,一个交互器和一个带有可选视图和演示者的构建器没有视图的RIB称为无头RIB。就像在VIPER架构中一样您使用路由器從一个RIB路由到另一个RIB,这将应用程序的整个运行时结构化为带有父RIB和子RIB的树形结构由于视图是可选的,因此与VIPER不同您的应用程序树结構可能会或可能不会模仿您的视图层次结构。

Builder负责为交互器路由器以及视图和演示者组装或初始化它们而获取或创建依赖关系。

路由器負责导航到特定的子RIB

Interactor负责所有业务逻辑并使用路由器启动路由。

演示者和视图通常组合在视图控制器中其中演示者负责按摩和格式化偠在视图中显示的数据。

View负责在屏幕上显示数据并收集用户输入

本文中涉及的问题涉及iOS开发人员应了解的广泛主题。这绝不是一个全面嘚清单

面试题持续整理更新中,如果你想一起进阶不妨添加一下交流群

面试题资料或者相关学习资料都在群文件中 进群即可下载!

}

我要回帖

更多关于 类与类之间的调用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信