有什么快速简便的方法可以使您的打印对帐单输出更整洁,更易读? 看看协议Custom String Convertible! 我发现该协议在我的项目中非常有用,并且想分享一下这是什么以及如何使用它的快速概述。 Apple的文档将“自定义字符串可转换”定义为“一种具有自定义文本表示形式的类型。”简而言之,真正发生的是,当您使类或结构符合“自定义字符串可转换”时,您会自动获得一个内置的description属性,即您可以将其设置为任意字符串。 这个超灵活的描述属性是“自定义字符串可转换”的核心,因此它对于创建清晰易读的输出代码如此有用。 在我们开始将Custom String Convertible应用于您的代码之前,让我们看一下没有此协议的代码…即我们要避免的事情! 从自定义类型开始: struct Dog { var品种:字符串 变量名称:字符串 变量年龄:整数 var color:字符串 } 现在,我们将创建几个Dog对象的实例,并将它们添加到dogs数组中。 var狗:[Dog] = [] let dog1 = Dog(品种:“ Beagle”,名称:“ Spot”,年龄:5,颜色:“ Brown and white”) let dog2 = Dog(品种:“贵宾犬”,名称:“蓬松”,年龄:2,颜色:“灰色”) let dog3 = Dog(品种:“拉布拉多”,名称:“ Buddy”,年龄:9,颜色:“黑色”) 狗= [dog1,dog2,dog3] 在此示例中,让我们从最大年龄到最小年龄对这些狗进行排序,并使用打印语句来确保我的排序方法有效。 func sortDogs(){ dogs = dogs.sorted {返回$ 0.age> $ 1.age} 打印(狗) […]
嗨,大家好! 我决定我也想发布一些我在编程时学到的概念。 对于那些不知道的人,我是一名软件工程师,目前专注于在Android中构建移动应用程序。 但是,我喜欢iOS,自2014年以来一直在Swift中制作应用。 这将简短明了,将来我可能会对此进行扩展。 什么是封包? 闭包是可以像变量一样传递的函数。 一种将闭包视为持有函数的类型的方法,即字符串,整数,双精度型。 了解功能也很重要。 函数是在Swift中使用func关键字定义的代码块。 函数可以采用并返回无,一个或多个参数。 为什么使用它们? 因为它们使用简单的语法,所以可以使代码更整洁并易于阅读。 它们还使您可以以一种不太复杂的方式灵活地重用代码。 通过降低复杂性,这也使您的代码更易于调试。 我该如何写闭包? 这是闭包的几种形式: var noParametersOrReturn:()->()= { 打印(“无参数或返回类型”) } var noParametersReturnString:()->字符串= { 返回“无参数,返回字符串” } 如果闭包是函数的最后一个参数,则尾随闭包允许您简化语法。 func sayHiAndRunClosure(name: String, closure: () -> ()) { print(“Hi, \(name)!”) closure() } sayHiAndRunClosure(name: “Mary”) { print(“The closure was ran!”) } 有一个更短的语法。 闭包参数可以按位置($ 0,$ 1,…)而不是名称进行引用。 设数字= [1,1,2,5] 让奇数=数字。过滤器{$ […]
当我遇到这个问题时; 我很困惑。 我打开操场检查他们的行为。 我很惊讶地知道很多事情,所以逐步写下我的知识。 首先,我声明了3个字符串,如下所示, var str1:字符串! var str2:字符串? var str3:字符串 打印(STR1)->无 打印(STR2)->无 print(str3)//初始化之前使用的变量’str3’。 在打印str3出现错误,这意味着我们必须先初始化所有非可选变量,然后才能使用它们。 需要注意的是str1为nil 。 现在让我们初始化为零 str1 =零 str2 =零 str3 = nil //无法将nil分配给’String’类型 再次,我得到了str3错误,这意味着我们无法将nil分配给非可选变量。 虽然我们可以将str1初始化为nil 。 然后我通过分配一些值来打印它们, str1 =“字符串” str2 =“字符串” str3 =“字符串” print(str1)->字符串 print(str2)->可选(String) print(str3)->字符串 str1正在打印“字符串”。 怎么样? 现在最后检查 print(str1!)->字符串 什么? 说真的,我可以拆开str1 。 我以为,它已经解开,所以不允许我解开。 我真的被这个练习所吸引,现在我已经理解了这些声明之间的区别。 让我们来看看, 可选 -表示常量或变量允许为“无值”。 可以使用可选绑定检查它们,以查看该值是否存在。 隐式解开可选 -有时我们知道,可选在初始化后将始终具有价值。 但是在声明它的时候,我们不确定它的价值。 […]
在我的工作中使用了很多在Interface Builder中设计的自定义视图,我发现自己重写了相同的代码以使XIB中的视图无效。 然后,在阅读了一些文章之后,我发现协议可能是实现此目的的最佳方法(它有助于编写更少的代码)。 这里我们有协议: 使用此协议,自定义视图在被包含它的情节提要实例化时将自动从关联的XIB加载其自身的内容,而无需编写任何其他代码。 这将只是一行代码。 一种 当用作XIB的文件的所有者时,UIView子类可以符合此协议。 笔尖需要与类名称相同的名称,并且需要位于该类的束中。 如何使用: 声明您的自定义视图符合NibFileOwnerLoadable协议。 然后,您应该使用loadNibContent()覆盖init?(coder:) ,以便将其关联的XIB作为子视图加载并自动添加约束。 因此,假设您的自定义UIView子类名为SearchView,则代码将为: 最后一堂SearchView:UIView,NibFileOwnerLoadable { … 需要初始化吗?(编码器aDecoder:NSCoder){ super.init(编码器:aDecoder) loadNibContent() } } 在无法使用loadNibContent()的情况下(例如,因为您需要对子视图进行特定的配置),无论如何,您都可以使用此协议通过使用InstantiateFromNib()来仅实例化XIB的视图。 谢谢你的时间! 希望本文对您有所帮助。 在Twitter上联系: stefanofrosoni
Swift是一种移动的编程语言。 它发展很快。 增长的下一步是ABI稳定性,将在Swift 5中引入 应用程序二进制接口(ABI)定义软件程序如何与已编译的二进制文件进行通信。 ABI由 数据布局,它定义数据类型实例在内存中的布局方式。 调用约定,该约定控制如何传递函数的参数以及如何检索返回值 运行时和标准库 类型元数据,包含有关类型的信息 所有权决定 Mangling,使用哪个编译器唯一地标识源中标识符的名称。 ABI稳定性意味着定义一组约定,规则并获得标准化表示,以便将来的编译器版本生成兼容的二进制文件。 当前,如果将用Objective-C编写的应用程序迁移到Swift,则该应用程序的大小至少增加5-10 MB。 这是因为每个使用Swift构建的应用都在其中嵌入了Swift框架。 当Swift 5在2019年初实现ABI稳定性时,Swift标准库和运行时将被嵌入到iOS中,并且所有应用程序都将能够使用它。 因此,您的应用大小会减少。 实现ABI稳定性的第一步是源兼容性。 源代码兼容性意味着较新的编译器可以编译用较早版本的Swift编写的代码。 使用Swift 4.2,可以实现Source兼容性。 您的应用程序现在可以包含符合不同版本的Swift(例如Swift 3或Swift 4)的库。 具有ABI稳定性,编译器生成的二进制二进制文件的未来版本需要在不破坏现有应用程序的情况下工作。 例如:如果Swift团队决定将来支持高级并发机制,则其设计必须符合ABI。 他们可以在内部进行许多更改,但必须向后兼容。 目前,SDK开发人员无法使用Swift分发封闭源二进制文件。 到目前为止,他们都依赖Objective-C。 使用ABI,接下来是模块格式的稳定性。 完成后,SDK开发人员将能够将Swift源代码作为封闭的二进制文件与模块文件(标头文件)一起提供。 Swift ABI的稳定性将是这门年轻语言的成熟点。 我的Twitter Deekshith Bellare
Segues允许应用程序转换视图并将数据从一个视图传递到另一个视图。 例如,如果您在iPhone上打开通讯录,则可以使用segue从所有联系人的完整列表转到一个特定的联系人,并说明了从一个屏幕切换到另一个屏幕的操作以及屏幕上显示的信息。目标屏幕。 segue的概念很简单,但是当我第一次遇到将segue付诸实践的代码时,我很难理解每个部分的含义。 当编码概念开始让我有些迷惑时,我发现可视化和创建类比非常有用。 因此,在本博文中,我将深入研究下面的示例segue代码,并创建一个故事以帮助直观地看到这些代码段的含义。 我假设读者熟悉以下基础知识:调用prepareForSegue函数的语法,情节提要的组成部分,Xcode项目中需要的文件等,等等。基本上,本文的目的不是引导您逐步了解实现segue所需的各个部分,而是帮助您描述功能中发生的事情。 让我们开始! 我们的故事 我们的故事发生在杂货店。 这家杂货店有很多过道。 通道7是谷物通道,即最佳通道。 如此多的美味含糖早餐美食! 这是我们故事的起点。 这家杂货店使用端盖或每个过道的末端来展示特殊物品和促销。 看看下面的端盖图片。 谷物交易多么划算! 由于这是一个令人难以置信的故事,所以我们也可以说杂货店使用很酷的机器人程序(是的,实际的程序,是字面上的类推),在商店中进行任何繁重的物品搬运或运输。 Segues并不是很聪明,因此他们需要商店中人员的详细说明,以便能够将物品从一个位置带到另一个位置,以及在新位置更新标志和价格。 当然,segues只了解用Swift编写的方向! 今天,杂货店经理想在端盖上设置谷物的特殊展示。 正在进行大甩卖! 经理需要将segue用于将谷物从第 7通道拖到 端盖 。 1.选择segue 首先,经理需要确保自己的工作正确无误。 (如果她不小心抓住了一个编程的从通道4拿走糖果并将其放入结账通道的方法呢?!)这是她写这些指令的方式: 仅在此标记具有标识符“ moveCereal”的情况下,其余说明才能继续进行,这意味着管理者的标记将从第7通道移动到端盖。 (在现实世界中,这些连接详细信息是在情节提要中设置的。)太好了! 2.告诉segue去哪里 现在,经理告诉segue去哪里。 segue的最终目标是结束盖帽,在这里称为EndCapViewController 。 最终的目的地简称为newLocation 。 为了可视化,这是在segue将任何内容移到那里之前, newLocation端盖现在的样子。 请注意,没有任何标志说明正在出售什么,而且货架上没有任何物品! segue稍后将填充这些内容。 3.告诉segue在哪里可以找到正确的谷物 接下来,经理告诉segue到底在哪里找到需要移动的谷物。 Segues不能分开阅读或分辨谷物箱,但可以在网格上或架子上找到坐标! 这些架子坐标称为indexPathsForSelectedItems。 但是segue应该将这些架子坐标应用于哪些架子? aisle7Shelves ,当然是在起始位置! (在现实世界中,这是当前视图或开始视图上的UICollectionView的名称。) 同时,segue会自动假设它将要接收许多货架坐标(请注意,它是索引Paths ForSelected Items的索引,而不是索引Path ForSelected Item的索引!),但是经理实际上只想要一种谷物,因此只需要一组谷物坐标。 既然是这种情况,她将专门指示segue仅遵循第一组坐标: […]
第4章:闭包和强大的闭包参考周期 面试是一个非常热门的话题,因为它提供了从初学者到专家级别的问题,而且大多数工程师在讨论中都对它感到困惑,即使您尝试在现实生活中使用它,也可能会遇到一些情况,混淆了使用什么和不使用什么! Swift中的闭包类似于C和Objective-C中的闭包。 闭包是可以独立传递的功能块,可以在代码中传递和使用。 闭包表达式语法 逃逸关闭 当闭包作为函数的参数传递给闭包时,闭包被认为是对函数的转义 ,但是在函数返回后会被调用。 声明将闭包作为其参数之一的函数时,可以在参数的类型之前编写@escaping ,以指示允许对闭包进行转义。 reversedNames = names.sorted(by:{s1中的s1,s2> s2})// (第1行 ) reversedNames = names.sorted(by:{$ 0> $ 1})// (第2行) 这两行都在做相同的事情, 第1行称为单表达式闭包的隐式返回, 第2行称为速记参数名 ,可用于通过$0 , $1 , $2名称引用闭包的参数值。上。 封闭的强大参考周期 之所以会出现这种强引用循环,是因为闭包(如类)是引用类型 。 案例:如果您将闭包分配给类实例的属性,并且该闭包的主体捕获该实例。 说明:之所以可能发生此捕获,是因为闭包的主体访问实例的属性,例如self.someProperty ,或者因为闭包调用了实例上的方法,例如self.someMethod() 。 在任何一种情况下,这些访问都会导致闭包“捕获” self ,从而创建一个强大的参考周期。 解决方案:弱引用或无主引用,弱引用或无主引用的适当选择取决于代码不同部分之间的关系。 问题:无主还是弱? 您应该使用两种参考类型中的哪一种? “只要有效,在引用生命周期中的某个时候变为零就使用弱引用。 相反,当您知道引用在初始化期间被设置为永远不会为零时,请使用无主引用。” “当闭包及其捕获的实例将始终相互引用且始终在同一时间解除分配时,将闭包中的捕获定义为未拥有的引用。” 有两种可能的方案: 闭包与捕获的对象具有相同的生存期,因此闭包只有在对象可以到达之前才可以到达。 外部对象和闭包具有相同的生存期(例如,和对象及其父对象之间的简单反向引用)。 在这种情况下,您应该将引用声明为Unown 。 一个常见的例子是在许多小闭包的例子中使用的[unowned self] ,这些小闭包在其父母的上下文中做某事,并且没有被其他地方引用或传递而不会超过其父母的寿命。 […]
如果将闭包作为参数传递给函数,并且在函数返回后调用该闭包,则闭包正在转义。 在Swift 2中,您可以使用@noescape属性标记一个函数参数,告诉编译器不允许传递给该函数的闭包对函数主体进行转义。 在Swift 2中,闭包默认情况下转义了函数体。 在Swift 3中,当函数具有闭包作为参数时。 我们需要将其明确标记为@ 转义,因为 默认情况下,闭包在swift 3中不会转义。 为什么不逃避? 默认情况下,使闭包不转义有很多好处。 最明显的好处是性能和编译器优化代码的能力。 如果编译器知道闭包是非转义的,则它可以处理内存管理的许多细节。 这也意味着您可以在无转义的闭包中使用self关键字而不会出现问题,因为闭包是在函数返回之前被调用的。 在闭包中不需要使用对self的弱引用。 这是一个免费的不错的好处。 例如 : 在Swift 3中,如果您有一个带有闭包参数的函数,并将其分配给在函数外部定义的变量,则此闭包可以通过存储在此外部变量中而从函数主体中逸出。 Swift编译器将给出如下错误 因此,您必须将闭包显式设置为@escaping
2.在此示例中,打开* .intentdefinition,然后添加New Intent,为其命名,然后设置重要部分是Parameters and Shortcut Types (如果需要用户确认,请检查☑️需要用户确认),在此示例中,我将跳过确认过程。 查看苹果文档以获取更多信息。 参数让我们使用Custom类型。 快捷方式类型的 标题/副标题将显示为Siri结果。 3.不要忘记设置响应, 响应 模板中的模板将再次显示为Siri结果。 4.创建新的目标选择 意图扩展和意图UI扩展。 5.在您的应用程序目标中创建IntentHandler类, NSObject和IntentHandling的子类也在Inspectors中选择Target Intent和IntentUI 。 在“确认”部分中,Soup Chef App尝试显示订单确认视图,当Siri订购Soup Chef App时,也尝试在代码中显示发票,但两者均未显示在Siri屏幕中。 您可以在Siri响应文本中看到[object Object] ,这意味着Response中不支持Decimal 。 Apple可能会很快更新SiriKit和Siri Shortcuts文档,请等待。 源代码 neungnarakjung / CookBook-Siri-快捷方式-示例 CookBook-Siri-Shortcuts-示例– Siri快捷测试版(XCode10 beta) github.com
今年即将结束,我们想为 Yummypets 应用程序 共享iOS堆栈 。 我们开始做吧! 码 该应用程序的97%是完全用Swift编写的。 总共46k行代码。 MVC 整个应用程序遵循good’ol MVC模式 。 当控制器太大时,我们会将它们重构为较小的控制器。 核心 我们所有的模型逻辑和网络代码都封装在Core.framework中。 这迫使我们将逻辑和视图代码分开。 这也具有使我们能够在不启动完整应用程序的情况下处理纯逻辑的巧妙优势。 网络层 我们的网络层隐藏在Api界面后面。 这意味着我们的View控制器对我们的网络库一无所知。 这也意味着我们可以将api实现切换为返回虚拟数据以进行测试,而无需触摸控制器\ o /的任何一行 。 图像加载和缓存🖼 我们使用Kingfisher异步加载图像和缓存处理。 该api很简单,但是非常可定制。 我们以前使用AlamofireImage,但由于性能原因而切换到Kingfisher。 联网☁️ 对于网络,我们使用ws☁️,这是一个简单的基于诺言的JSON网络库。 它具有打包3件东西的优点: 出色的Alamofire库,用于网络请求 一个简单的Promise库 一个简单的JSON解析库 这种整洁的抽象层使我们能够有效地添加和维护路由。 异步🕐 我们严重依赖Promises来保持我们的异步代码清洁和可维护 。 为此,我们使用🎬 JSON解析⚙️ 我们对JSON解析库有严格的要求:不应强迫我们对模型进行子类化,同时支持类和结构,并且要尽可能简单。 为此,我们使用Arrow🏹,它将为我们处理所有样板JSON解析代码,并保持模型映射的清洁和可维护。 布局🏝 我们不会使用Storyboard或Xibs ,原因是我们在此不做详细说明。 TLDR : 更容易维护 。 您可以在这里找到有关此问题的精彩文章。 是的,我们所有的视图和TableView单元格都在代码中! 这带来了巨大的好处! 如您所知,纯自动布局的代码非常冗长 ,这就是为什么我们使用Stevia🍃使其保持可读性和可维护性 […]