Tag: Swift编程

无极内部

我如何在Swift中构建Promise / A +库 Hydra的GitHub页面 上也提供了这篇文章 介绍 在Objective-C中进行异步编程从来都不是真正令人兴奋的经历。 我们已经使用了多年的代表(我仍然记得我第一次见到它,那是在2001年左右,当时我在Mac OS X上玩过Cocoa的乐趣) ,不久前我们也参加了完成会议处理程序。 但是,这两个过程都不能很好地扩展,并且不能提供可靠的错误处理机制 ,特别是由于语言本身的某些限制( 是的,您几乎可以在C语言中执行任何操作,但这不在本文的讨论范围之内 )。 在厄运的回调金字塔(也称为回调地狱)中迷失自己是很容易的,并且通常您的代码最终变得不那么优雅,阅读和维护起来也不那么简单。 Promises可以帮助我们编写更好的代码,并且在诸如await/async之类的结构的帮助下,处理异步编程确实是一种乐趣。 早在2016年11月,我就决定在Promise库中工作,只是为了进一步了解如何实现此概念以及如何使用Swift这样的现代语言来实现这一概念。 在本文中,我将更深入地了解Promise库:Hydra的体系结构。 在本文中,您不会了解如何在下一个杀手级应用程序中使用Hydra,但将了解它在幕后的工作方式(但是我为Hydra编写了完整的文档,可在GitHub上找到它)。 什么是诺言? 承诺是将来可能会产生单一价值的对象。 该值可以是您期望的对象(即JSON响应)或失败原因(即网络错误) 。 许诺可能处于以下状态之一:已resolved (或已fulfilled ),已rejected或pending 。 一个承诺开始于待处理状态,可以转换到两个状态中的另一个状态。 一旦解决,就无法重新安置。 Promise的用户可以附加回调(或观察者)以获取有关任何状态更改的通知。 then ,Promise的最常见的运算符是and catch ,用于获取Promise的值或捕获任何发生的错误。 但是,还有其他几个运算符可以大大简化网络代码的编写方式,但我们稍后会介绍。 一点历史 Promise的历史可以追溯到很久以前,即1980年代初。 最早的实现最早是在1980年代以Prolog和Lisp等语言出现的。 “ Promise ”一词由Barbara Liskov和Liuba Shrira在一篇名为“ Promises:分布式系统中对高效异步过程调用的语言支持”的学术论文中提出(1988)。 随着承诺兴趣的增长,ECMAScript标准重新定义了Promise的新规范:Promise / A +用于定义Promise的边界和行为。 符合Promise / A +实施的主要规则是: Promise或“ […]

创建一个不使用情节提要的新iOS项目

故事板很棒,它们绝对有目的,并且使快速构建iOS应用程序变得容易。 也就是说,我发现在较大的应用程序上,它们会出现许多问题。 主要是它们很难进行版本控制,并且可能变得庞大。 我敢肯定那里有克服这些问题的团队,但对我个人而言,不使用它们会更容易。 大多数长期应用似乎都使用了直接编写的代码,或者混合了nib / xib文件和代码。 无论出于何种原因,Apple不再提供非故事板单页应用程序,这意味着我们需要做一些事情来创建一个。 我发现摆脱它们,创建一个nav或tab控制器并将其用作我的根源更加自由,而不必再考虑segues了。 无论如何,我们看到的所有奇特的东西都可以通过自定义转换来完成。 还有人在开发周期的后期决定,他们希望VC转移到应用程序中完全不同的位置,从而减少了纠缠。 无论哪种方式,您都会遇到一个应用程序,无论出于何种原因,其中一项要求是该应用程序不能使用情节提要,因此最好知道如何创建该应用程序。 这也是我们在情节提要之前制作应用程序的方式,并且总是有机会最终导致不使用它们的旧项目。 步骤1.创建一个新项目 打开xcode并创建一个新的Single View App,将其命名为任意名称。 出于本教程的目的,我将其命名为测试,不包括任何测试。 当我们打开它时,我们将有一个Main.storyboard和一个ViewController.swift文件。 2.删除情节提要 选择ViewController.swift和Main.storyboard并将其删除。 选择将它们移到垃圾桶 接下来,我们需要通过从我们的info.plist中删除主故事板,让该应用知道不使用主故事板。 打开您的Info.plist,然后单击“主故事板文件库名称”旁边的减号按钮。 步骤3.创建一个新的主ViewController,以在应用启动时使用 创建一个名为MainVC的新文件 这是UIViewController的子类。 单击“ Also create XIB file旁边的检查。 出于本教程的目的,我们将使用xib文件,但是也没有理由。 创建它之后,打开AppDelegate.swift 。 在didFinishLaunchingWithOptions我们需要让应用知道在启动时使用我们的MainVC 。 添加以下代码: self.window = UIWindow(框架:UIScreen.main.bounds) self.window?.rootViewController = MainVC(nibName:“ MainVC”,包:nil) self.window?.makeKeyAndVisible() 就是这样,构建并运行您的应用程序,您应该看到MainVC 。 您现在没有情节提要了。

Swift中的自动引用计数(ARC)

程序运行时,会分配有限数量的资源。 记忆是最重要的之一。 因此,这种类型的内存浪费会阻碍程序性能,甚至导致崩溃。 ARC为我们设置了打破这些周期的任务。 那么,我们如何才能打破这些循环? 好吧,这就是我下一篇文章的主题: 如何使用弱引用和无主引用来中断引用周期? 敬请关注… 如果您喜欢该帖子,请点击❤️按钮并进行宣传。 请在下面发表评论,以提供您的反馈并帮助我改善内容。

使用地图解开Swift Optionals

阅读优秀程序员编写的源代码是改进我们编码方式的最简单方法。 我一直很欣赏objc.io上的人编写的代码。 有一天,我读了约翰·桑德尔(John Sundell)的一篇关于Swift中的期货和承诺的文章。 由于具有可选功能,在阅读该文章时我还不了解,因此理解起来并不容易。 Futures and Promises本身是一个复杂的概念,但是我在一些代码片段中发现的是一种不常见的方法来解开optionals 。 本文还可以帮助理解John Sundell编写的代码。 我们通常使用if let或guard let 解开可选内容的语法。 通常用于解开可选字符串( 或任何其他类型的optional )的代码如下 现在让我们讨论解开可选内容的不常见方式。 我们可以使用map函数来展开可选对象。 你不惊讶吗? 好吧,我是。 我一直以为map应该与Sequences一起使用。 现在这个想法已经改变。 根据Apple的文档,关于可选方法的map方法的描述如下 当此Optional实例不为nil ,计算给定的闭包,将未包装的值作为参数传递。 这意味着如果一个可选参数具有某个值 ,将执行给map函数的闭包 。 特别是闭包将收到解包的可选参数。 因此,我们可以使用下面的代码使用map函数来展开可选字符串。 现在,如果您尝试阅读有关Swift中的期货和承诺的文章,您将更好地理解它。 现在,我们知道了另一种安全地包装可选内容的方法,这是我们可以用来提高代码可读性的方法。 你喜欢这篇文章吗? 也许尝试以下方法之一: 在Swift中使用ExpressibleByArrayLiteral简化生活 驯服宽松的通知 断点作为调试内容提供者 在核心数据中使用可变类型作为可转换属性的危险

Swift#1:元组或元组?

问题 Entédéveloppeur,关于如何解决唐纳德的问题。 Dans le cas d’unedonnée很简单,例如在renvoie comme valeur de retour d’une fonction上。 Dans le cas d’unedonnéeComplexe,在适当的“人间结构”上。 Mais si cettedonnéen’est ni trop简单,ni trop复合物? 恩·贾瓦(En JAVA),杜瓦河沿岸(envoy de renvoyer deux)的康菲恩·德·富瓦(Trois Valeurs sans pour autantcréerun tableau)? 解决方案存在于Swift中: les tuples 。 Quéest-ceque les tuples? 永久组团的便利性的元帅,新古典主义风格的无价之宝。 瓦伦西亚和瓦卢斯的元帅同盟 斯威夫特的自由主义者丹尼斯·拉·库普里斯(Das la librairie standard de Swift),前女同性恋夫妇(clé, valeur) valeur (clé, valeur)专注于类型Dictionary上的结构和功能,而您可以根据自己的喜好来选择。 语言元组: let person =(名称:“ […]

Swift 4中的主函数

目的 介绍在Swift 4中使用函数的所有有用信息。希望到本文结尾,您将对在Swift 4中使用函数有深刻的了解,然后将其优雅地应用到您的项目中。 我给出的例子将是相关的。 基本上使用我们已经知道的东西来解释一些新东西。 我会尽力而为。 清晰,简洁,实用。 目前为止就这样了。 打开Playground,让我们直接潜水。 什么是功能? 函数是执行特定任务的独立代码块。 – 苹果 我们定义函数来执行某些任务,稍后可以调用。 就像具有已定义功能的“打开”按钮的交流遥控器一样。 我们可以通过按“开”按钮来调用该已定义的函数,AC会尝试冻结您。 有史以来最简单的功能 让我们从零地面开始,然后逐步发展。 这样我们就不会错过任何一件事情。 在我下面是一个空函数,请检查一下: func emptyFunction(){ } 我可以在我的代码中这样调用: emptyFunction() 目前,它绝对不执行任何操作。 这样,我们就可以剖析函数并了解Swift中创建函数的每个细节。 与iOS开发人员,代码访问员和书面交流时,下一部分特别有用。 要“命令”我们刚刚对另一个人所做的事情,可以说定义一个称为“空函数”的函数。 func→定义一个功能 emptyFunction→函数名称 现在可以使用 如今,我们中的很多人都沉迷于皇家冲突。 也许只是我。 无论如何,让我们从Clash Royale的场景中举例说明。 我们将定义一个函数,对其进行调用,然后逐步学习一些东西。 让我们来看看它的作用。 限定 尝试看看是否可以根据我收到的描述提供一个功能。 定义一个名为“ battle with”的函数,该函数带有两个参数。 第一个参数是字符串类型的播放器名称。 第二个参数是我们要使用的战斗甲板。 如果您没有获得参数部分,请不要担心,因为我尚未向您介绍参数,但是在本文中将进行详细介绍。 这是函数编写方式的示例: func BattleWith(playerName名称:String,BattleDeck卡座:Int = 2)->字符串{ return(“使用甲板编号\(甲板)的战斗\(名称)。”) } 不要惊慌。 […]

有关保留计数的问题。

请在回复中写下您的答案 变量rollNumber(Program 1.0)的保留计数是多少? 2.变量rollNumber(程序1.1)的保留计数是多少? 2.1。 globalArray(程序1.1)的保留计数是多少? 3.地址变量(程序1.2)的保留计数是多少? 4. profileImage(程序1.3)的保留计数是多少? 5. yellowView(程序1.4)的保留计数是多少? 6.地址变量(程序1.5)的保留计数是多少?

关于setUp()和tearDown()的全部

Xcode运行测试时,它将独立调用每个测试方法。 因此,每种方法都必须准备并清理所有分配。 为此,它具有两个重要的方法setUp()和tearDown() 。 setUp() —在调用给定类中的每个测试方法之前,将调用此方法。 tearDown() —调用给定类中的每个测试方法后,将调用此方法。 每个类测试都从类 setUp() 方法执行开始。 然后针对每种测试方法 1.分配了一个新的类实例。 2.执行其实例setUp()方法。 3.运行测试。 4.执行实例tearDown()方法。 对于该类中的所有测试方法,都将重复此顺序。 在最后一个测试方法之后,当实例tearDown()已运行时,Xcode将执行类teardown方法。 您可以通过5种不同的方式自定义setUp()和teardown() , 1.覆盖setUp()类方法以设置所有测试方法的初始状态。 2.覆盖setUp()实例方法以在执行每个测试方法之前重置初始状态。 3.在执行测试方法期间,可以使用addTearDownBlock(_:)方法使用addTearDownBlock(_:)的拆卸代码块。 4.覆盖每个测试方法执行后要清除的tearDown()实例方法。 5.在执行所有测试方法后,重写tearDown()类方法以进行清理。 让我们检查以下测试的执行情况, //资源: developer.apple.comclass SetUpAndTearDownExampleTestCase:XCTestCase { 覆盖类func setUp(){// 1。 super.setUp() //这是setUp()类方法。 //在第一个测试方法开始之前被调用。 //在此处设置所有总体初始状态。 } 覆盖func setUp(){// 2。 super.setUp() //这是setUp()实例方法。 //在每个测试方法开始之前调用它。 //在此处设置任何每次测试状态。 } func testMethod1(){// 3。 //这是第一个测试方法。 //您的测试代码在这里。 addTeardownBlock {// 4。 //当testMethod1()结束时调用。 […]

在项目中管理快速扩展的更好方法

我们如何在项目中管理扩展。 下面来自我的项目的截图说明了一切。 例如,我有一个简单的扩展UIColor + toImage,用于从一种颜色生成图像。 用法。 让redImage = UIColor.red.toImage() 完美不是吗? 可读性 。 1.没有人可以轻易猜出此函数是来自原始UIColor类还是来自我自定义的扩展(除非深入阅读该定义。) 2.该扩展会在不同的项目中重复使用,因此我们很可能希望它们继续进行到下一个项目中。 很难猜测它所属的名称空间。 一种简单而古老的方法是在扩展名中的所有函数名称之前使用带有_( 下划线 )的前缀。 例如。 my_或abc_ 让redImage = UIColor.red.my_toImage() 但是这种解决方案是无法管理的,因为我们必须确保所有函数都以my_作为前缀。 如果我们使用my.toImage()而不是my_toImage()怎么办。 因此,想法是制作一个名为MyHelper的单个模块类/结构,其中将包含所有扩展方法。 如果需要,我们也可以将功能分组为扩展。 MyHelperCompatible协议具有` my`变量,该变量保存整个MyHelper类/结构对象。 现在,我们可以根据用途扩展MyHelper 。 例如。 在上面的文件中,我们可以添加与UIColor相关的其他帮助器函数。 同样,我们可以将alls函数分组为MyHelper扩展。 最后,我们可以像下面一样访问toImage()。 让redImage = UIColor.red.my.toImage() 从现在开始,我们只需要创建上面的扩展和方法即可。 无论如何,我们都想停止这种行为,我们可以注释掉/删除一致性部分。 //扩展名UIColor:MyHelperCompatible {} 提示 :将所有一致性保持在一个地方而不是分散在项目周围是一件好事,这样您就可以更好地控制。 我知道这似乎有点棘手,并且需要花费额外的精力来设置一次,但是我相信,随着项目的发展,它会大有帮助。

Swift中的内存管理

什么是弱变量? 您知道吗,在IBOutlets前面。 查看苹果的文档,我发现了自动引用计数(ARC)。 Apple使用ARC进行内存管理并跟踪内存使用情况。 诸如强,弱或无主之类的关键字会在何时添加或释放保留计数时向ARC发出信号。 坚强的默认Default 每次我们声明一个class属性时,默认值都是一个强引用。 神奇宝贝类{ var名称:String =“ Pikachu” var skill:Skill = Skill() } 班级技能{ var类型:字符串=“ Pika Thunder” } 让myPokemon = Pokemon() 打印(“我的新皮卡丘技能:”,myPokemon.skill.type) 宠物小精灵具有技能属性。 当我们创建Pokemon类时,也会创建Skill类。 因此,Pokemon类具有指向Skill类的强大指针,并增加了Skill的保留计数。 当Pokemon类被释放后,指针将被删除,Skill类将其保留计数减少为零。 参考不足 等一下,如果指针指向两个方向的是双向关系呢? 如果Skill类具有指向Pokemon类的指针,并且Pokemon类被分配了一个值,我们将创建一个保留周期 🔄这可能导致内存泄漏🙁 class Pokemon {var name:String =“ Pikachu” var技能:Skill = Skill()} class Skill {var type:String =“ Pika Thunder” var pokemon:Pokemon?} let myPokemon = Pokemon()myPokemon.skill.pokemon […]