您可能已经听说CoreNFC已在Beta中发布,并且只能在iPhone 7和iOS 11上运行! 是Apple强迫用户迁移到最新智能手机的策略,还是一个真正的硬件问题,使iPhone 6s无法使用NFC? 这是一个悬而未决的问题,但是在不久的将来,iPhone 7将成为最受欢迎的iPhone,但仍然! 一段时间以来,当公司想要在产品上实现NFC标签读取时,总是会遇到功能退回的情况。 在实践中是什么意思? 适用于iOS App的QR Code和App方案以及适用于Android的NFC!。这次结束了! 。 好吧,它如何工作? 如我们所知,Apple有任何限制:)。 答案是不 ! 当然,除了NFC付款。 但是,您可能需要在Apple Development Portal中进行一些额外的配置。 组态 首先,您需要按照以下说明创建或修改现有的应用ID,以激活NFC读取功能 然后,您在Xcode 9(撰写此博客时为Beta)上创建一个Playground或一个新项目。 我们将创建一个名为NFCReader的小类,该类将负责处理NFC Reading处理 首先,我们将创建该类并导入CoreNFC框架。 因此,NFC阅读由NFC阅读器会话管理。 我们只是在初始化类时进行基本的初始化。 该会话具有一个代理(将在下面进行说明)和一个名为invalidateAfterFirstRead的属性。 此属性允许您的应用程序仅读取一次标签。 您是否可以激活它,这完全取决于您的App 。 完成此操作后,我们将开始会话。 考虑到实际的应用程序,此操作可能在其他位置并经过特定用户交互之后执行。 根据文档所述,CoreNFC框架会继续编译并仅在实际设备上起作用 ,这是继续之前的重要提示! 因此,这意味着您必须在目标前面的通用iOS设备上才能使用iOS 11 Beta构建或成为真实设备。 委托实施 CoreNFC具有两个主要的委托函数,可让您知道NFC数据是否已交换或会话是否无效。 然后,利用有效负载信息,您可以在应用程序中做任何您想做的事情。 好吧,这对于接收有效载荷数据和进行会话管理非常有用,但是我怎么知道我检测到周围的标签? NFCNDEFReaderSession是基于其具体类NFCReaderSession的 并拥有自己的泛型委托: 而已 ! 如您所见,在iOS中集成NFC并不复杂。 您只需要等待iOS 11发布,然后专注于NFC阅读实施和周围的动画! 啊,我几乎忘记了,但是它在Apple Watch OS […]
另一个WWDC越来越强大,我希望大家对Apple的所有新公告感到高兴。 如果您还没有,那么可以查看一下经过很好概括的内容— WWDC 2017初始印象 因此,我不会重复该博客上已经介绍的内容,但是这里的想法是分享我们对所有新功能的想法以及它们将如何影响我们作为iOS开发人员的工作。 核心ML 通过去年的Siri更新,很明显苹果公司知道将机器学习计算推向终端设备的潜力。 随着Core ML的推出,应用程序可以实现的可能性是无限的。 到目前为止,如果添加计算的唯一方法是编写低级代码并在Metal中运行(您太极端了,请尝试一下)。 但是现在,添加任何ML模型并直接在应用程序中使用非常容易。 这是苹果公司投资创建全新的Framework Metal(3年前)的真正帮助所在。 Metal的第一个用例只是用于图形渲染以替换另一个现有框架(如OpenGL),但现在它在许多方面都提供了帮助,包括ML和VR开发/渲染。 此外,硬件和软件设计所有权也有帮助。 ARKit 最终,苹果加入了聚会。 这是改变游戏规则的游戏,与其他平台不同,您可以通过Apis获得丰富,便捷的视觉跟踪,场景检测和渲染。 就是这样,您不必担心其他事情。 Unity&UnrealEngine将支持所有ARKit API。 这将对他们有所帮助,因为他们是游戏开发和3d渲染的主要参与者。 通过iOS 11在设备上采用HEVC / H.265 我认为这也是巨大的,因为它将对性能产生影响(由于存储和传输的数据较少,因此也会对环境产生影响)。 尽管HEVC的生产水平在几年前就已开始实施,但我们可以认为Apple至少在移动设备方面是最早的采用者。 XCTest的新功能 我们对此感到非常兴奋,我认为这将有助于更快地进行回归调试。 到现在为止,您还必须设置其他一些第三方,如果我们希望在CI管道中使用这种功能。 有关更多信息,请参阅此文档。 VR开发 尽管在VR应用程序上工作非常令人兴奋,但它并不像使用ARKit那样简单。 但是在建立框架方面做得很好。 希望我将在单独的博客文章中提供有关此&ARKit的更详细的更新。 HTC VIVE的默认支持-低延迟直接显示。 默认支持Unity&STEAM VR。 Xcode 9 我在社区中听到的所有内容都是对新Xcode 9的速度和新功能的称赞。 其中很少有: Xcode中的默认XCode构建服务器:现在,我们无需安装Sever应用程序即可设置Xcode bot。 如果他们将Xcode服务器用于CI或测试,这将非常有用。 我们还从头开始用Swift编写了新的Build系统 。 这很重要,期待建设愉快。 无线开发:这将使开发人员的生活更加轻松。 现在,我们可以在多个模拟器上进行测试。 强大的新编辑器:许多新功能。 轻松快捷的重构 […]
随着iOS 11的发布,Apple开始让我们在iOS上使用NFC。 目前,只能读取内容。 1)启用NFC标签读取功能 目前,您需要转到“证书,标识符和配置文件”页面(https://developer.apple.com/account/ios/identifier/bundle),以将NFC功能手动添加到您的应用程序。 并将其添加到您的应用程序的魅力: 3)实现NFCNDEFReaderSessionDelegate 您可以复制该扩展名并将其粘贴到您的代码中,只需记住使用您的类名对其进行更新。 4)开始扫描
今年,我有一个绝佳的机会参加了在加利福尼亚州圣何塞举行的Apple开发者大会。 拖放,Core ML,AR Kit是Apple发布的一些API和框架。 在这些新的API和框架中,我更着迷于在单个应用程序或单独的应用程序中将内容从一个地方拖放到另一个地方的功能。 总览 拖放利用Multi-Touch的强大功能,使您可以在iPad上以自然的方式在应用程序之间移动内容。 您只需按住图像,文件或选定的文本并将其拖到他们想要的位置即可。 阅读完Apple的拖放文档后,我将构建一个应用程序,该应用程序仅允许您从浏览器或具有拖动功能的另一个应用程序中拖动图像并将其拖放到视图中。 入门 首先,打开Xcode 9 https://developer.apple.com/download/并创建一个新项目。 选择单视图应用程序,然后将Swift作为您的语言。 更改您的组织名称和标识符。 添加UIDropInteractionDelegate协议 打开ViewController.Swift并扩展UIDropInteractionDelegate协议。 在viewDidLoad()内部添加 self.view.addInteraction(UIDropInteraction(委托:self)。 UIDropInteraction允许用户将项目放置到视图上,并使用委托实例化对象并响应来自放置会话的调用。 在viewDidLoad()下面实现UIDropInteractionDelegate协议,添加canHandle会话方法 func dropInteraction(_交互:UIDropInteraction,canHandle 会话:UIDropSession)->布尔{ 返回session.canLoadObjects(ofClass:UIImage.self) } 当放置会话的触摸超过潜在的目标视图时,将调用canHandle会话方法,这是您的应用程序有机会告诉系统是否要使用拖动项。 在canHandle会话方法下面添加sessionDidUpdate方法 func dropInteraction(_交互:UIDropInteraction, sessionDidUpdate会话:UIDropSession)-> UIDropProposal { 返回UIDropProposal(操作:.copy) } 当放置会话以下列任何一种方式更改时,将调用此委托方法:其可视表示的接触点已进入放置交互的视图,或已在视图中移动,或在控件内部时将拖动项添加到会话中。要使视图有资格接受放置会话中的数据,必须实现此方法。 func dropInteraction(_交互:UIDropInteraction,performDrop 会话:UIDropSession){ 用于session.items { item.itemProvider.loadObject(ofClass:UIImage.self, completeHandler:{{obj,err)在 如果让err = err { 打印(“ Errror”,err) } 守卫让draggedItem = obj作为? UIImage其他 {返回} […]
今年WWDC上宣布的一项不错的新功能是分阶段发布。 这是一项新功能,能够在7天内逐步向用户发布应用更新。 长期以来,这一直使iOS开发人员羡慕他们的Android开发人员同事。 分阶段发布的功能与Android分阶段发布的功能不同,但它肯定比同时向数百万用户发布的功能要好得多。 那么它是怎样工作的? 如果您选择分阶段发布,则iTunes Connect将逐步向选择在7天之内进行自动更新的用户发布新版本。 所有用户仍然可以绕过此操作,如果选择的话,可以直接进入应用商店以下载新版本。 它的增加如下: 第一天:1% 第2天:2% 第三天:5% 第4天:10% 第5天:20% 第6天:50% 第7天:100% 如果有问题怎么办? 您可以随时暂停发布,最长总暂停时间为30天。 这是一个累积数字,如果您取消暂停并再次暂停,则不会重置。 如果存在无法解决的关键问题,则可以停止销售该应用程序版本,尽管这样做会从商店中删除该应用程序,因此这是最后的选择。 如果我想向所有人释放怎么办? 您可以随时取消分阶段发布并释放给所有用户。 在iTunes Connect中,您只需按“发布给所有用户”。 这听起来不错,我该如何选择加入? 选择加入确实非常简单,而且只要您没有问题,一切都可以为您管理,因此一切顺利。 iTunes Connect中有一个新的单选按钮,“使用分阶段发行”。 如果选择了,就是这样! is这是每个版本的功能,因此由您决定是否需要通过此分阶段的过程。 如何监视发布状态? 同样,从iTunes Connect。 有了分阶段发布的新视图,它可以向您显示当前所处的发布阶段。
以下是WWDC 2017(会议201)的大部分“可可接触新功能”会议的快速回顾。 这都是现场输入的内容,因此,如果某些内容不正确,请随时纠正我。 生产率 拖放 通过创建UIDragInteraction(UIInteraction的子类)并将其附加到您希望具有Draggable的视图(并分配其委托),来启用Drag。 委托人提供拖动项目的数据,允许自定义“提升”动画并自定义draggin预览。 通过创建UIDropInteraction并以类似方式设置其委托来启用Drop。 委托允许在拖动移动时更新UI,接收拖放上的常规数据并自定义拖放动画。 开箱即用地支持许多UIKit元素-TableView,CollectionView,TextView,TextField和WebView。 文件管理 引入了新的文件资源管理器,该文件资源管理器允许在我们的应用程序中进行演示。 UIDoumentBrowserViewController是我们可以在应用程序中显示的ViewController。 它是高度可定制的,并允许访问设备内容,iCloud内容和外部云服务。 协调文件访问至关重要,因为我们不能指望我们的应用程序是唯一可以触摸某些文件/资产的应用程序。 可以通过使用NSFileCoordinator / UIDocument来完成。 用户界面优化 大标题导航栏可以具有内置的搜索栏,但是当您向上滚动内容时,搜索栏将随着大标题折叠为常规小标题而折叠,就像我们习惯于iOS 10。 在大多数情况下,这几乎可以自动完成,因为系统可以通过将UINavigationBar.prefersLargeTitle设置为true来自动处理它。 您还可以使用UINavigationItem.largeTitleDisplayMode来围绕导航级别以更精细的方式控制大标题显示模式。 通过设置UINavigationBar.searchBarController启用统一搜索栏。 通常,导航控制器/堆栈中的顶部控制器将是唯一使用“大型”样式标题的控制器,而内部控制器应使用标准的小变化。 导航栏中有一个内置的Pull-to-refresh,看起来很棒。 我们不能一直指望导航栏的静态高度,因为它可能会更改不同内容类型的高度。 在大多数情况下,这将由各种UINavigation类自动处理。 UIView上有一个新的safeAreaInsets.top属性,我们可以准确而可靠地使用它来通过导航栏知道“模糊”区域的大小。 还有一个底线值。 ( safeAreaInsets.bottom ) 您也可以使用safeAreaLayoutGuide 。 对于手动布局,您可以手动阅读safeAreaInsets并订阅安全区域大小的更改。 现在, UINavigationController不再像使用安全插入一样控制插入值,因此在Scroll View上设置手动插入应该不再像以前那样费时了。 UIScrollView具有称为contentInsetAdjustmentBehavior和contentInsetAdjustmentBehavior新属性,可用于手动定义插图在UIScrollView上的行为。 UITableViewCell现在支持使用新的UIContextualAction类在左侧和右侧进行内置的滑动操作。 看起来与UITableRowAction工作原理类似,但是更加精致,因为您可以单独使用UISwipeActionsConfiguration对这些UIContextualAction进行分组。 UITableView上有一个新的属性,称为“ separatorInsetReference ,可让您设置插图的值是绝对值还是“增量”,例如,在引用中,插图将是以前的插图。 斯威夫特4和基金会 归档Swift本机类型 新的Codable协议允许更轻松地“存档”和“取消存档”,并且默认情况下允许他们参与NSCoding。 关键路径 新的KeyPath类型具有用于文字语法的选项(例如\Object.path.subPath ),因此您可以动态创建一个密钥路径,然后使用collection[keyPath: someKeyPath] 。 使用object.obserer(keyPath) { […]
Apple上周在圣何塞举行的WWDC 2017主题演讲和国情咨文中宣布了Xcode 9以及Swift4。使它成为Swift 4标准库的最重要的变化之一就是一系列编码,解码和解码协议。类型实例的序列化,允许用户与JSON以及与本地磁盘进行相互转换。 这些协议(最著名的是Codable , Encodable和Decodable旨在作为Swift的本机答案,以解决开发人员在Swift 3或更早版本中序列化对象时遇到的一些限制。 这些协议仅在一个星期前就已经流行了,但是Apple可以在线获取一些出色的文档。 我花了一些时间对这些API进行试验,以进一步了解它们的工作原理,可能的功能以及在生产代码库中使用它们可能遇到的一些优点和缺点。 到目前为止,Swift社区中最大的开放问题之一是“您使用哪个第三方框架对JSON反序列化? 还是你自己滚?”。 自从我第一次开始编写Swift以来,我已经尝试了几种第三方框架并开发了自己的框架。 我经常对此感到沮丧的是,每个框架都带来了自己独特的方法,但是它们似乎都误选了可选内容,缺乏强大的错误处理能力,并且使用了不直观的自定义运算符。 Swift 4的Codable协议现在为解决该问题提供了一种通用且推荐的方法,因此我根据一些我经常会遇到的关键用例进行了实验。 反序列化 假设您有一个结构Product并且想从网络请求中收到的JSON响应中反序列化实例。 确保Product和任何自定义属性类型均符合协议Codable (如果不序列化回JSON,则仅Decodable )。 在要将Data对象反序列化为Product模型的那一点上,初始化JSONDecoder对象,然后调用decoder.decode(_: from:) 。 如果解码操作失败,则此函数将引发错误,因此您可能需要将其包装在do,try catch语句中。 就是这样。 假设Product模型上的所有属性名称与您要反序列化的JSON结构中的字段名称完全对应,Swift将处理初始化模型实例所需的所有工作。 序列化 将Product序列化回JSON仅需要模型及其所有自定义属性类型符合协议Codable (如果您不从JSON反序列化,则仅Encodable )。 在您想要将Product实例序列化为要在网络请求或其他任何地方发送的Data ,请初始化JSONEncoder对象,然后调用encode(_:) 。 如果编码操作失败,此函数也会引发错误,请随意将其包装起来,然后尝试再次捕获。 嵌套类型 在Swift 4中,对具有同样也是Codable类型的属性的Product模型进行反序列化变得非常容易。非常简单,只需确保每个嵌套类型都符合Codable (或者在需要时仅Encodable / Decodable )。 就像您期望的那样, JSONDecoder将以与解码顶级对象相同的方式来处理嵌套属性的解码。 自定义属性名称 当然,使用JSON从未如此简单。 作为移动工程师,我们经常无法控制我们正在使用的Network API,并且想要为要从JSON有效负载解码的属性定义自定义字段名称。 重要的是要了解,默认情况下,Swift会自动使用您定义为字段名称的属性名称来从JSON进行解码。 在Codable类型上为属性定义自定义字段名称就像在对象CodingKeys上定义一个枚举一样简单,该对象的rawValue类型为String并符合CodingKey协议。 您需要为模型上的每个属性定义一个案例。 然后,将每种情况的RawValue用作要从JSON解码的JSON字段名称。 自定义键路径 在我尝试使用更复杂的键路径和JSON结构进行的简短介绍中,似乎Swift的处理这些方法需要一些习惯,并且涉及很多样板。 […]
苹果公司致力于减少客户流失 编辑(2017年7月16日):苹果发布了此处描述的功能! 相关链接显示在底部。 继续逐渐成为对订阅的一种温和的迷恋,我非常荣幸地参加了Apple的主要活动,并探讨了订阅中出现的所有闪亮的新事物。 众所周知,在过去的一年中,App Store中订阅服务的公告和增长迅速。 它从开放所有类别的订阅开始,到第二年订阅者大幅削减Apple专利使用费,然后在全年继续提供大量功能发布,例如地理定价,新的免费试用选项和期限,订阅事件报告等。 在大多数情况下,这些举动都是促成因素,允许并鼓励许多开发人员转向新模型,这种做法是正确的。 但是,随着这些开胃菜的到来,我们都越来越渴望更多。 实际上,JoyTunes的团队已经仔细收集了一些统计数据和可行的见解,以供下一步使用。 幸运的是,苹果公司惊人的订阅团队也有类似的想法,这使我们进入了WWDC17。 那么,WWDC17发生了什么? tl; dr苹果决定加倍减少流失,包括非自愿取消,自愿取消和退款。 (流失率=付费用户流失率) 以下是JoyTunes团队发现的最令人兴奋的主要变化,然后对这些变化的重要性和现实生活数据进行了一些解释。 将帐单重试窗口从几个小时延长至(最多)60天 从Apple发送的特殊情况下的实时服务器事件,例如用户降级,退款和过期订阅的续订(例如在计费问题之后),这对于跨平台服务很重要 按用户标记计费问题,自动续订取消,退款,甚至发生退款的原因(来自AppleCare)(!!!) 对于退款,这尤其棒,因为之前没有与退款相关的信息 有点尴尬,但是这些变化实际上使我眼中充满了喜悦的眼泪。 要了解原因,让我们更深入地研究这些变化。 非自愿流失 让我们从非自愿的流失(也称为帐单问题)开始。 这些是由于信用卡过期,商店信用额不足,卡被盗以及Apple在收取续订费用时遇到的任何其他困难而导致的取消。 我猜这听起来太微不足道了,上帝知道我们也是这么想的。 也就是说,直到我们在相当新且隐藏得很深的订阅事件报告(ITC→销售和趋势→下拉菜单中的报告→下载订阅报告)中检查了取消原因之后,才发现有22%的取消是由于该原因而发生的。 进入WWDC17时,我们有以下问题– 22%被认为是标准的吗? 如果没有,wtf ?! 我们在做什么错? 如果是这样,wtf ?! 苹果可以帮助解决这个问题吗? 第一个发现是22%实际上是令人恐惧的标准,从某种意义上来说,这令人放心–至少不仅仅是我们! 此外,计费问题通常被认为是#3取消原因。 今天,当出现计费问题时,Apple会尝试让用户在几个小时内解决这些问题。 例如,如果您的卡被盗了,或者您像我们其他人一样只是一个懒惰的被动人物,那么时间就不会那么宽裕。 现在,已将其延长到最多60天(!!!),具体取决于发现的问题。 我的猜测是,这一变化可能单方面导致整体订阅收入大增。 此外,Apple在收据数据中添加了新字段,用于发出计费问题信号,以便我们(应用程序开发人员)可以警告用户有关情况,将其移至临时访问权限或任何其他解决方案。 最重要的是,Apple很快将针对几种特殊情况发出服务器通知。 其中,标记为已解决帐单问题,以便可以更新成员资格。 这对于跨平台服务非常重要,在跨平台服务中,用户可能会尝试访问网站,例如,没有先打开应用程序,因此我们不知道结算问题已得到解决。 换句话说,Apple认真对待其作为超越应用程序的订阅付款方式的责任 。 应当指出,服务器通知非常重要,特别是因为我们每天增加的订阅数量越来越多,并且要一直获取所有这些信息的最新挑战变得越来越困难。 自愿流失 此类别包括为什么任何人都想取消服务的自动更新的常规原因,其中之一就是过时的恐惧。 实际上,我们的数据显示,年度计划中自动续订的取消中有20%以上是在前几天发生的(请参见图表)。 基本上,人们想要该服务,但是只是想确保它甚至在使用前都不会更新。 尽管我们可以做很多事情来提高用户对我们高质量音乐学习服务的信心,但是到目前为止,还没有办法知道我们是否在进行改进,因为只有在订阅到期后才能看到这些匿名取消。 实际上,我们需要等一整年才能知道我们的努力是否产生了影响…… 好吧,苹果改变了这一点。 […]
这是我们在WWDC 2017的“国情咨文”演讲期间从苹果公司获得的一切的简要回顾。 源代码编辑器 从头开始用Swift重写 内置降价编辑器 更好的修复(内联并且不破坏格式) 300多种新的诊断程序,分析仪及其修复程序 文件打开速度提高3倍,滚动速度达到60 fps,行跳移速度提高了50倍 在Playgrounds的代码编辑器中标记化(悬停时按住Cmd) 动作的上下文菜单(在标记化结构时点按) 全新的重构系统 Cmd +/-调整代码文本的大小 SDK版本可用性修复 协议实施存根修复 “提取”将实现移至其自己的方法/ let 重命名/编辑范围 跨源代码进行全局重命名/重构-跨所有片实时更新 开源转换/动作-开发人员可能会引入新的东西 斯威夫特4 字符串现在是字符集,就像数组一样 带”””多行字符串文字 单边范围和使用下标的字符串切片 Unicode 9 Grapheme Breaking(Unicode 9字素突破)-更好地支持Unicode(相对于旧版本,它实际上是正确的) 可编码协议:编码/解码JSON / plist的超级超级简单方法: try JSONEncoder().encode(Codable) vs try JSONDecoder.decode(Type.self, from: payload) Xcode 9 Swift语言版本(3.2 / 4.0)-允许逐步升级到Swift 4 构建时间:混合和匹配Swift / Objective-C的速度应提高40% 整个模块优化应该有更好的构建时间(大约2倍)(从Xcode 8.3.2开始,理论上来说) 核心技术 索引器 完全重新架构 快速打开x35更快 […]
这是WWDC 2017演讲的简短表格摘要,仅重点说明要点和关键示例: UIKit应用程序中面向协议和价值的编程– WWDC 2016 –视频– Apple Developer 在去年的面向协议的编程和具有值类型的会议上构建更好的应用程序的基础上,今年的…… developer.apple.com 您可以从WWDC视频中下载完整的示例代码: https://developer.apple.com/library/content/LucidDreams/Introduction/Intro.html#//apple_ref/doc/uid/TP40017334 本地推理-关于功能的独立思考。 您不必了解应用程序的整个上下文即可维护各个功能。 您应该只能够应用局部推理来理解各个功能。 MVC:模型存储您的数据。 视图将显示它。 控制器在两者之间进行协调。 使用Structs之类的Value类型与Classs之类的引用类型相比,可以促进局部推理,简化关系,并使代码更具可测试性。 结构在其所有成员上赋予值语义和独立存储。 在模型层中使用值类型是标准且无争议的。 但是,一旦您开始在其他地方(例如控制器)使用值类型,人们通常会犹豫不决,或者不知道该怎么做。 例如,子类化一个tableview单元是有限的,因为您不能在不是单元格的其他视图中重用该代码。 代替使用UITableViewCell子类,我们可以将其更改为结构并实现layout(in rect:CGRect)方法: 然后,我们更新单元格子类以在上述布局结构中调用图形调用。 现在,我们还可以从其他区域调用此绘图代码,而不仅仅是表格视图单元格: 通过为布局代码提供样本以进行内部布局,然后验证生成的框架,也可以更轻松地对布局代码进行单元测试。 我们不必考虑该视图使用或替代的其他特定视图功能。 现在,我们可以更改布局对象以使用协议,而不是引用UIViews。 这样我们就可以将布局逻辑也应用于其他类型的对象(例如Sprite Kit对象),而不仅仅是UIView子类。 下面我们还使用“ Retroactive Modeling”使UIView和SKNode都符合我们的布局协议: 协议是通过继承实现多态性的绝佳解决方案,因为您可以将相同的额外行为应用于任何不相关的类型。 当前,“内容”和“装饰”都可以是任何类型的对象,并且它们不必是同一类型。 如果我们想将两个约束为相同类型,可以使用泛型通过在结构上指定所需的类型来实现。 (现在,内容和装饰都必须与传入的Child类型相同): 使用泛型还可以为编译器提供有关代码正在执行的操作的更多信息,并允许我们进一步优化代码以提高性能。 继承牺牲了“局部推理”,因为您必须考虑父类在做什么,它如何工作,将要更改或覆盖的内容以及如何使其与父行为一起工作。 如果要继承系统对象,那么这些对象也将非常复杂。 它使您的思维在父母和班级之间跳来跳去,系统变得更难以理解。 合成意味着将许多较小的片段组合在一起,以制成较大的片段。 类很昂贵,会导致堆分配。 使用类来构成视图非常浪费。 结构更便宜,并且具有有价值的语义(因此具有更好的封装性)。 没有人可以修改您的副本。 您可以使用以下结构为不同的布局类编写视图组成代码: 但是,仍然存在更好的方法,只需简单地使布局结构也符合布局协议即可。 (从它们两个中都删除冗余方法布局): 现在,我们的视图和布局都使用相同的Layout方法,将自己定位在给定的rect中是他们的责任。 合成使我们能够以声明的方式构建高级布局: 如果我们希望布局以正确的顺序相互嵌入视图(层叠),则每个布局都需要以正确的顺序将其子级返回给其所有者。 因此,我们可以在内容上实现get方法,并让每个实现者返回其所有视图。 […]