Tag: swift

Swift中的App架构和对象组成

对象组合是面向对象编程的核心概念。 对象可以包含其他对象,有时会创建复杂的层次结构。 在本文中,我想展示如何设计这种架构。 在一个实际的示例中,您将看到处理复杂的层次结构很简单,而对象和层次结构可以重用。 面向对象的设计过程包括规划对象如何连接和交互以创建零件或完整系统。 我们都习惯了Model-View-Controller体系结构,该体系结构定义了包含视图和模型的控制器对象。 这些组成部分共同构成了应用程序的基础。 形成树结构的递归类型使事情变得有趣。 递归组合很简单,可以用来表示任何潜在的复杂层次结构。 组合模式是“设计模式:可重用的面向对象软件的元素”一书中描述的结构模式。 它描述了如何构建由两种对象的类组成的类层次结构:原始对象和复合对象。 将对象组合到树结构中以表示部分整个层次结构。 复合可以使客户统一对待单个对象和对象组成。 设计模式:可重用的面向对象软件的元素 复合模式定义了下一个参与者: 组件是一个抽象接口。 它声明函数并由客户端使用。 Leaf实现了由Component接口声明的功能。 复合工具组成。 它包含子组件数组。 Composite通过委派(转发)对其子级的调用来实现Component接口声明的功能。 客户端是通过Component接口使用合成的代码。 我们可以像这样实现Composite模式: 现实生活中的实现可能会略有不同。 常见的变化是Component,Leaf和Composite是同一对象。 使用树结构进行组合是一种非常强大的模式,它对应用程序体系结构具有很多好处: 将复杂的任务分解为小部分。 组件解决小任务。 组成一棵树以解决更大的任务。 与复杂结构进行交互的方式与与单个实例进行交互的方式相同。 组件树具有与单个组件相同的接口。 单一责任原则。 组件负责单个功能。 它可以是特定于域的,也可以是特定于组成的(例如按特定顺序安排孩子)。 可重用性。 组件是可重用的,可以在更大的层次结构中使用组件树来解决更大的任务。 可测试性。 由于组件和组件树是独立的,因此可以进行单元测试。 应用各种设计模式的机会。 树结构可以很好地与各种创建,结构和行为设计模式配合使用。 简单。 最后但并非最不重要的。 在特殊情况下,复合模式只需要一个类即可实现。 树和树上的操作对于开发人员是众所周知的。 难以置信? 让我们看一些例子。 UIView UIView的层次结构可能是树结构最突出的示例。 视图是应用程序用户界面的基本构建块。 可以将视图嵌套在其他视图中以创建视图层次结构。 例如,我们使用小的UIView节点构造复杂的树。 我们可以按功能对视图进行分组: 基础UIView类。 它定义了所有视图共有的行为,呈现内容以及处理与该内容的任何交互。 显示内容。 […]

将CocoaPods与预先构建的框架一起使用而不是源文件

介绍cocoapods-binary cocoapods-binary是CocoaPods的插件,旨在将预构建的框架链接到项目。 一旦执行pod install命令,它将自动为每个依赖项预先构建一个框架,并将结果链接到您的项目。 这样就可以减少项目的构建时间 ,因为您将仅构建源代码,而不是每次都构建依赖关系。 这确实是朝正确方向迈出的一步。 安装cocoapods-binary 为了安装cocoapods-binary ,我们需要运行brew install cocoapods-binary或gem install cocoapods-binary命令。 在我们的Podfile中使用cocoapods-binary 我们需要在Podfile的开头添加以下行: plugin ‘cocoapods-binary’ 如果我们要对所有依赖项使用预构建的框架,则还可以添加all_binary! 在任何目标或定义之前。 如果我们再次运行pod install ,它将为每个依赖项预先构建一个框架,并将其与我们的项目链接。 如果我们清理并构建它,它将不再浪费大量时间来构建依赖项。 将比特码嵌入到预先构建的框架中 如果我们想将Bitcode嵌入到我们的iOS应用程序中,我们还需要将其嵌入到我们的依赖项中 。 为了使其与预先构建的框架一起使用,我们需要在Podfile中通过添加enable_bitcode_for_prebuilt_frameworks!进行指定enable_bitcode_for_prebuilt_frameworks! 和keep_source_code_for_prebuilt_frameworks! 毕竟all_binary! 。 请注意,您将需要重新运行pod install才能看到更改。 添加例外 如果我们尝试使用预先构建的框架(例如Google Maps iOS SDK)添加某些依赖项,则这些依赖项将不起作用 。 由于它要求将GoogleMaps.bundle文件添加到主项目并在构建时进行复制,因此不建议使用预构建的框架。 为了使它们正常工作,我们需要通过将:binary => false设置为我们要排除的每个依赖项来添加一个例外 。 pod ‘GoogleMaps’, :binary => false 让我们看一个例子 考虑到我们有以下Podfile: 插件’cocoapods-binary’ 平台:ios,“ 12.0” use_frameworks! […]

雨燕数据

Tipe data merupakan salah satu hal yang penting sekali untuk di mengerti di luar kepala。 Kenapa,karna semua berawal dari situ ketika kita memprogram。 Kita harus benar-bear memahami apa tipe数据来源,bagaimana mengolahnya,dan bagaimana menggunakannya。 内置于Swift的yang ada的Berikut tipe数据: // 整数 var myInteger:Int = 1 //双 var myDouble:Double = 1.23456 //浮动 var myFloat:Float = 1.23 //字串 var myString:String =“世界你好!” […]

iOS面试问题(快速)-第3部分

1.什么是封闭,我们可以在哪里使用? 它们是自包含的代码块 ,可以在代码中传递和使用。 Swift中的闭包类似于C和Objective-C中的块以及 其他编程语言中的lambda 。 它们与函数几乎相同,但不一定具有名称。 无需声明每个参数的类型,如果这样做,则无需声明闭包的返回类型。 单击 链接 以了解所有类型的闭包语法。 2.什么是转义/不转义闭包? @nonescaping闭包:(默认闭包) 当在函数的参数中传递闭包时,请在函数主体执行并返回编译器之前使用它。 当函数结束时 ,传递的闭包超出范围,并且在内存中不再存在。 @转义闭包: 。 在函数的参数中传递闭包时,请在函数体执行并返回编译器后使用它。 当函数结束时 ,传递的闭包的作用域存在并存在于内存中,直到执行闭包为止。 链接 3. 提到Swift中可用的集合类型是什么? 数组 -用于按顺序存储相同类型的多个值。 集 -用于以无序方式存储相同类型的不同值。 字典 —用于以无序方式存储具有键-值对关联的值。 4.如何在Swift中定义基类? 在Swift中,这些类不是从基类继承的,并且您在未指定其超类的情况下定义的类将自动成为基类。 5.什么是反初始化器以及如何用Swift编写? 在取消分配类实例之前立即声明一个反初始化器。 您使用deinit关键字编写反初始化器。 如果需要在取消分配对象之前执行某些操作或清理,请使用它。 例如 ,如果您创建一个自定义类来打开文件并向其中写入一些数据,则可能需要在释放该类实例之前关闭该文件。 反初始化器的编写没有任何括号 ,并且没有任何参数。 deinit { //执行反初始化 } 6.双重问号“ ??”有什么用? ? 该运算符称为nil合并运算符 。当可选参数为nil时,我们使用它来提供默认值。 let a: String? = nil let […]

Apple Swift套件管理员:深入研究

苹果已经发布了自己的软件包管理器,称为“ Swift Package Manager”,以共享和分发Swift软件包。 很高兴知道Apple正在努力替代iOS开发世界中当前最受欢迎和最讨厌的软件包管理器,即CocoaPodsand Carthage。 在本文中,我们将介绍软件包管理的基础知识,并深入研究iOS中的软件包管理,尤其是Swift Package Manager。 当前的iOS软件包管理器 大多数现代语言都带有用于代码分发的官方解决方案,例如Ruby的RubyGems,PHP的Composer,NodeJS的NPM。 在iOS开发环境中,开发人员必须依赖第三方依赖项管理工具,例如CocoaPods和Carthage。 iOS中的程序包管理器还有另外一项工作,即在下载之上构建代码。 在动态框架的情况下,程序包管理器应该能够下载并构建框架。 您可以在此处阅读有关iOS静态和动态库的更多信息。 让我们简要地看看它们是如何工作的。 我们将使用’SwiftyJSON’这是非常流行的Swift库来解析JSON作为示例。 可可豆 CocoaPods作为Ruby库提供,需要作为RubyGem安装。 CocoaPods是使用Ruby构建的,并且可以使用OS X上可用的默认Ruby安装。 $ sudo gem install cocoapods 可以使用“ pod init”命令初始化CocoaPods,该命令将创建模板Podfile,但我们可以创建自己的简单“ Podfile”。 典型的“ Podfile”将如下所示 平台:ios,“ 8.0” use_frameworks! 以“ MyApp”为目标 pod’SwiftyJSON’,’〜> 2.3′ 结束 现在,我们可以使用魔术命令下载依赖项 $ pod安装 CocoPods和Xcode 上面的命令(pod安装)非常神奇,它可以对我们的Xcode项目进行很多更改。 在大多数情况下,很难理解发生了什么变化。 这可能是大多数开发人员讨厌CocoaPods的原因。 CocoaPods对Xcode进行了以下更改。 .xcworkspace文件(.xcodeproj顶部的另一个文件,用于打开项目) Podfile.lock(CocoaPods的锁定版本) “ Pods”目录(目录包含Pod依赖项的源代码) Xcode设置中有很多东西! 现在,我们必须使用.xcworkspace打开项目以导入您的依赖项,否则CocoaPods无法正常工作。 CocoaPods的优缺点 […]

在iOS中设计实体层次结构:类继承v组成

设计不佳的实体层次结构可能像这座塔一样不稳定。 不灵活的设计可能无法接受新的实体或特征,并且可能导致大量的代码复制和粘贴。 层次结构中更下层的实体可能会导致不必要的行为或意外的实现,并且大量的覆盖可能导致较差的动态调度。 简而言之,正确设计很重要! 设计这种层次结构有两种常用方法: 类继承 和 组合 ,您可能会惊讶地发现一种方法明显优于另一种方法。 在本文中,我们将使用这两种方法设计一个简单的层次结构,以讨论它们的优点和缺点。 让我们开始吧! 方法1:类继承 类继承是在OOP中设计实体层次结构的经典方法,即使是初学者,也将很快熟悉本节中的概念。 作为一点点回顾,让我们提醒自己,继承是一种基本行为,已植入到类中,但未在结构中找到。 出于本文的目的,我们将构建以下层次结构的代码表示形式: 在代码中,它看起来像这样: 在这种情况下,不能将任何功能放在Bird超类中,因为它们都不是所有四个Bird子类都通用的。 相反,我们有不同的组合。 为了使这些功能在需要的地方可用,我们被迫做这样的事情: 即使一眼就能看出这是一个糟糕的解决方案,原因有几个。 首先,有很多重复,将相同的方法实现复制到不同的类中。 试想一下,如果我们需要对这些方法之一进行更改,那么现在我们需要在多个位置进行相同的更改。 接下来,它也打破了单一责任原则。 就Puffin而言,我们在单个类中实现了所有三种方法。 为了代码的可维护性,我们理想地希望看到封装在不同实体中的这些不同职责。 有人可能会争辩说,可以通过一些“创造性”子类来减少复制的数量,但这不可避免地导致了继承杂耍行为,这种行为只会随着新方法的引入而变得更加复杂,或者新类仅需要某些继承的方法而变得更加复杂。 。 我们最终得到了一个非常脆弱的层次结构,在该层次结构中,超类的单个更改可能在继承链的更下方产生无法预测的结果。 除此之外,当我们查看开始的层次结构图时,我们被提醒,我们的理想是将所有鸟子类都置于同一级别,这是用这种方法无法实现的。 那么为什么类继承不能给我们想要的结果呢? 构架此讨论的一种有用方法是考虑“是”与“具有”的关系。 类继承仅限于表示“ is-a”关系:很好地描述了海雀 “ is-a” Bird和Bird “ is-a(n)” Animal 。 但是,当我们尝试表示“具有”关系时,通常会达不到要求。 在这种情况下,我们可以将“具有”表示为一种属性(“具有喙”)或一种方法(“具有飞行能力”)。 我们看到想要添加swim() , walk()和run()的功能未在我们的鸟子类中一致地应用,这并不罕见。 在您脑海中越是用“ is-a”和“ has-a”观察世界,您就越会意识到自然世界并不是那么容易装箱。 方法2:通过协议组成 因此,现在让我们通过合成解决相同的问题。 以下方法由四人帮提出,用一种优雅的方式描述了这种方法: 编程到接口,而不是实现。 在iOS中,我们通过使用协议定义接口。 任何采用协议的实体都必须在合同上遵守所要求的接口,这实质上就是上述短语要求我们执行的操作。 现在,我们的基本设置如下所示: […]

Swift中的字符串,字符和性能-深入探讨

扫描令牌所用时间的三分之二全部花在了用于Character类型的初始化程序中。 到底是怎么回事? 初始化程序的第一个参数标签提供了一个小提示: _builtinExtendedGraphemeClusterLiteral 。 注意单词“ literal”。此初始化程序不用于从我要遍历的字符串中提取Character值; 它用于从源代码中其他地方的文字文本创建Character值。 在nextToken下找到这些标记的唯一地方是我的令牌生成器的switch/case模式。 他们真的造成那么多的开销吗? 我们可以让Swift编译器使用-emit-sil选项发出“规范SIL”(Swift中级语言),以更仔细地了解如何将这些case模式编译为较低级的代码。 (我在存储库中包含了一个小脚本,该脚本可以执行此操作,并且还可以分解Swift符号。)让我们找到与匹配逗号字符的case模式对应的SIL(为简洁起见,重新格式化了行号和范围): %448 = string_literal utf8“,” %449 =应用%26(%448,%23,%24,%25): $ @ convention(method) (Builtin.RawPointer,Builtin.Word, Builtin.Int1,@ thin Character.Type)-> @owned字符 %449的第二行和第三行所示的方法签名%449其放弃,但我们可以通过查看值%26来确认它,该值是被调用的函数: %26 = function_ref @ Swift.Character.init( _builtinExtendedGraphemeClusterLiteral:Builtin.RawPointer, utf8CodeUnitCount:Builtin.Word, isASCII:Builtin.Int1)-> Swift.Character : $ @ convention(method)(Builtin.RawPointer,Builtin.Word, Builtin.Int1,@ thin Character.Type)-> @owned字符 这是什么意思呢? 这意味着, 每次通过扫描循环(即,针对字符串中的每个字符)时,Swift都会调用此初始化程序来创建case模式中的每个字符,以便将当前字符与该模式进行比较,直到找到匹配项为止;并且该初始化程序如果您习惯于字符类型实际上只是一个数字代码单元的语言,则它的成本将大大超出您的预期。 通过查看Swift标准库源代码,我们可以看到将字符串文字(例如”,” )转换为Character时发生的动作序列: 编译器将UTF-8编码的文字表示形式嵌入可执行文件的数据段中。 在使用文字的地方,Swift调用Character.init(_builtinExtendedGraphemeClusterLiteral:utf8CodeUnitCount:isASCII) , Character.init(_builtinExtendedGraphemeClusterLiteral:utf8CodeUnitCount:isASCII)其传递步骤1中嵌入的字符串数据的地址(源)。 反过来,此初始化程序在String上调用相同的初始化程序。 最终,分配了StringBuffer […]

Swift中的正则表达式

从更一般的意义上讲,正则表达式是我们在学校中学到的东西,但是它们经常出现在编程任务中,尤其是在处理文本时。 关于Stackoverflow有一个问题,询问有关识别段落中文本的子集的问题。 问题的前提是要预览新闻文章,其结尾包含整篇文章中剩​​余的字符数,例如[+6025个字符]。 目的是用显示“更多”的超链接替换该字符计数文本? 我首先想到的是,我们需要使用正则表达式在方括号之间找到文本。 然后,我们将文本替换为所需的文本,最后,我们需要添加文本属性,尤其是超链接。 哎呀,这似乎有很多事情要做,所以让我们一次一步。 Swift没有正则表达式类,因此您认为您需要使用来自objective-c世界的NSRegularExpressions ,但是,这是错误的。 Swift字符串会自动桥接到NSString ,这意味着String具有一些不错的功能,使我们能够轻松地(通过正则表达式)对String执行模式匹配。 最好的例子是NSString类的range(of:options:)方法。 该方法在字符串中搜索字符串,但是选项使它真正强大。 有少数可用的选项,例如不区分大小写,向后且正则表达式感兴趣。 这些选项是不言自明的,也许是正则表达式除外,它会将搜索字符串视为“与ICU兼容的正则表达式 ”。 太好了,我们只需要定义一个正则表达式并将其传递给方法range(of:options:) ,它将告诉我们是否存在匹配项以及找到文本的Range 。 现在,我们只需要创建一个用于输入的正则表达式即可。 定义正则表达式完全是另一回事。 如果您曾经在SO或现实世界中看过任何东西,它们很快就会变得非常复杂。 regexr.com是一个很好的参考站点,您可以在其中测试表达式并获得有关构造表达式的详细信息。 让我们花一点时间描述一下我们如何构造正则表达式模式。 我们将在这里采用介绍性方法,仅介绍一些基础知识。 如果我们要在字符串中搜索字母a ,则正则表达式将只是一个仅包含“ a”的模式。 同样,如果我们要按特定顺序搜索特定字符(例如cat ,则模式将为“ cat”。 这一切都很好,但是出于我们的目的,我们需要找到方括号[ ]以及这些方括号之间的所有文本。 我们需要一种更强大的模式。 输入元字符,即在正则表达式模式中具有特殊含义和功能的字符。 一些最重要的元字符是点. ,问号? ,星号* ,脱字号^ ,括号, ()和方括号[] 。 让我们快速回顾一下这些字符在正则表达式中的含义。 的. 表示基本上匹配任何字符,但换行符除外。 这对于我们的目的将是有用的,因为这就是我们想要放在方括号之间的任何字符。 方括号[]表示要匹配一个字符类,这表示要在方括号之间匹配几个字符中的一个。 例如,将您的模式定义为[if] ,它将在输入“ Swift”匹配i找到匹配项( i或f将是匹配项),以及在“ wit”或“ half”上匹配的项i和f分别。 您通常会看到这与字母[az]或大写[AZ]匹配,对于数字字符则为[0–9] 。 […]

尝试! 迅速开催前开トークへの期待を书いてみる(1)

尝试! 斯威夫特东京2019 今年もぼくは尝试! Swift Tokyo 2019に参加します。开催まで1ヶ月を切り,LTを含めたタイムテーブルも公开されました。まだいくつか未定のトークもありますが,タイムテーブルに书かれたトーク内容を読んで,个人ただし,完全に自分向けのメモのようなものなので,他の人が読んでも面白くないと思います🙏。 実际の発表内容とは全く违うかもしれません。また,スピーカーの方はぼくの期待と内容また全然违っていても気になさらずに予定定りなプレ表をしてください。余计なプレッシャーを与えるのは本意ではありません。 本机macOS应用程序,またはAppKitの世界 📆3/21 10:00🗣1024jp 请选择“ CotEditor”。 技术的な面だけでなく,思想やアート的なある种のエモい话もあるんじゃないかと期待しています。 脱Swiftリテラル初心者 📆3/21 10:25🗣Yuki Aki⚡️🎤 「えっ,Swiftリテラルに初心者とか上级者とかあるの!?」と目を引くタイトルがいいですね。 であるである点も考えるとそんなに难しい话までは踏み込まないでしょうし,こういう「コンパイラの気持ちを考える」话は好きなので,きっと楽しめるトークでしょう。 アクセシビリティのためのカラーコントラスト 📆3/21 10:35🗣利兹·马利 英语のトーク概要を読んだ方がわかりやすいかもしれませんが,科学的根拠に基づいた方程式を使って相対的な明るさを评価する话でしょうか。単なる感覚ではない定量的な评価方法はいいですね。 スピーカーは他の开発者との触れ合いを大事にしているようなので,トークの感想を伝えたいです。 迅捷之光 📆3/21 11:30🗣乔恩·泰特·比森 プ3Dプリンターのことはあまり知りませんが,アプリはこれでしょうか。 実际に使われている制品の开発における,Swiftの生きたテクニックなどが闻けるのではないかと期待しています。Swiftの良いところを再确认できるんじゃないでしょうか。 限定的なimportの明示とその效果 📆3/21 11:55🗣平野智也⚡️🎤 スピーカーはきつねの人🦊(noppeさん) ジュいえば,importってモジュール単位でしか指定したことがない気がします。 いったところの解说があるのだと思いますが,むしろ,文法よりもパフォーマンスやアプリサイズに关系するとは思っていなかったのでその话に期待しています。 协议/扩展名にジェネリクスを入れたい 📆3/21 12:05🗣吉村光 でもよくコの苦手なところです。でもよくコーディングしててコンパイラに怒られるところでもあります。 くら,ぼくはトークを闻いても半分くらいも咀嚼できない気がしますが,あとで何度も参照する资料が生まれる気がするのでスライドの公开を今から希望しておきます のと,型システム关连で出てくるカリー=ハワード同型対応(名前だけ闻いたことある!)の理解を助けてくれるんじゃないかと期待しています。 关键路径入门 📆3/21 12:30🗣Benedikt Terhechte スピーカーはHirundo(Swiftメーリングリストビューア)の作者ですね 自分の中ではSwiftの新しい机能だ,という点だけ记忆に​​あって実は使ったことがない机能です。どんな时に使えるかっていうのを知っておかないと使えることに気づかないので,ぜひこのトークでその辺りを勉强したいなと思っています。 まだまだ続くよ とここまででもお1日目午前のトーク7本はい日书きました。ここまででもお腹いっぱい感がありますが,これでまだ1/4です。次は1日目午后のトークについて书こうと思います。

JSON和Swift:简介

JSON是一种很棒的文件格式,可以方便且串行地传输数据。 对于那些不熟悉Swift和API的人,这可能是您第一次与JSON进行交互。 如果您不熟悉Swift语言,本文将作为介绍,以及解析JSON的指南。 重要的是要注意,Xcode中使用了一个新的,最近更新的版本。 但是,仍然建议您了解并熟悉旧模型。 不管您使用哪种方法,JSON的奇迹都使您可以接收和使用许多有组织的代码。 毫无疑问,当您继续使用Swift(尤其是API)时,您将变得对JSON非常熟悉。 请留意本文的第2部分,其中我深入了解了Swift 4和Xcode 9引入的JSON处理的最新更新。