在Swift中覆盖存储的属性: 快速存储的属性和计算的属性有两种属性 储存财产 存储的属性是与结构或类的实例相关联的变量。 Swift现在通过使用let和var分别表示常量和可变属性,使属性声明更加简洁 计算财产 除了存储的属性外,类,结构和枚举还可以定义计算的属性 ,而实际上并不存储值。 相反,它们提供了一个getter和一个可选的setter,以间接检索和设置其他属性和值。 现在的概念是我们不能覆盖存储的属性 它将引发错误,因为如果我们真的想覆盖存储的属性,则无法覆盖它,那么我们需要使其成为计算属性。 结论:如果要覆盖子类中的存储属性,则需要将其定义为计算属性。 进行一些扩展,有助于获得UIStoryboard对象以用于Application中存在的多个情节提要 通常,我们在一个项目中的不同模块中会使用多个情节提要,所以通常我们通过其名称来获取情节提要。 并且我们在此情节提要中实例化了适当的UIViewController,并针对项目中不同的不同情节提要反复进行此操作。 因此,更好的方法是创建UIStoryboard的扩展,并定义所有不同的Storyboard,然后在无需编写太多代码的情况下将其使用在任何您想使用的地方。 用法:就像我们要创建故事板主对象一样,我们只需编写以下行 它可以节省我们的时间,还可以避免错误输入(错误的故事板名称等) 创建用于实例化UIViewController的通用方法 通常,当我们从一个屏幕导航到另一个屏幕时,我们实例化一个UIViewController并将其推入导航控制器。 在这种情况下,我们需要编写类似的重复代码,而只需稍加修改即可。 因此,我将创建UIViewController的扩展,以减少我们的开发时间并保持我们的代码质量。 它还将减少重复的代码。 UIStoryboard和UIViewController扩展的组合用法 如果我们要实例化Main Storyboard中定义的UIViewController。 使用Main.storyboard中存在的标识符实例化UIViewController 2 。 如果要实例化xyz故事板中定义的UIViewController。 它将实例化OtherStoryBoard.storybard中定义的UIViewController。 重要说明 :-这里使用扩展UIViewController是其强制使用扩展UIStoryboard。 结论:正如我们看到的那样,扩展的巧妙使用将减少我们的工作量并保持代码质量。 我想提一个名字,没有他,这个博客是不可能的。特别感谢阿曼提供的宝贵意见。 面临的问题将邮件发送到Ved.bhumca11@gmail.com。
有很多关于使用Swift以安全类型进行网络层的文章。 无论使用哪种网络API,这些方法都依赖于返回正是我们期望的数据类型。 这个想法是利用Swift的类型推断/泛型能力来避免强制转换返回的类型。 在这篇文章中,我们将通过强耦合我们要获取的端点和它必须返回的数据类型来尝试进一步发展。 快速提醒 假设我们要获取“ dog.ceo ”端点之一。 通常从定义路线开始。 枚举对此非常有用: 让我们尝试滥用这种机制:在仍然使用相同端点的同时,我们尝试明确告诉编译器结果是“ Result ”。 如预期的那样,失败fails。 我们确实拥有一个编译时类型的安全网络层😏,并对我们的API进行了少量更改。 很酷。 感谢您的阅读,并随时提供反馈! 敬请关注。
“ 通用编程是一种计算机编程风格,其中,算法根据稍后要指定的类型编写,然后在需要以特定类型作为参数提供时将其实例化 。” — Wikipedia 使用泛型编写代码是一种编写函数和数据类型而无需指定需要使用哪种确切类型的方法。 顾名思义,泛型类型不是特定的。 通过使用泛型,我们可以编写非特定的代码,因此,我们可以以更清洁,错误更少的复杂方式抽象代码。 在第一部分的这篇文章中,我将讨论数组,字典和可选变量是泛型的示例。 第二部分将讨论编写通用数据类和结构,编写通用函数和约束通用类型。 第三部分将讨论“关联类型”和“通用where子句”。 泛型数组 数组是泛型类型的示例。 数组是容纳任何类型的事物的容器。 在Swift中,我们受益于类型推论,我们可以在不显式声明其类型的情况下创建数组。 由于我们不必指定任何数组的类型(因为可以推断出该数组的类型),因此该数组作为数据结构是通用的。 让月份= [“一月”,“二月”,“三月”] 上面,我有几个月的时间。 由于我给的数组类型参数是字符串,因此本月的实例被赋予了STRING的具体类型 。 换句话说,声明数组时应定义的类型。 数组的通用语法 尽管上述月份的数组未正式将类型声明为STRING,但是有一种通用的语法声明数组,如下所示: var springMonths:Array = [] 请注意,单词Array后跟尖括号中的类型。 我们可以在这些尖括号之间分配“通用类型”的名称。 对于泛型,规范是使用作为我们引用的任何泛型类型的占位符。 在数组上使用通用方法 数组是通用的,带有通用方法,例如.append() springMonths.append(“ March”) springMonths.append(“ April”) springMonths.append(“五月”) 您会在上面注意到,我在springMonths数组中附加了月份“ March”,“ April”和“ June”。 如果我接下来编写以下代码行,您会怎么办: springMonths.append(50) 如果您猜编译器会给我错误: 那你是对的! 由于我们声明了Array的类型为STRING,因此任何不是字符串的东西都会使编译器不满意。 泛型词典 字典也是泛型的,因为我不必直接指定每个键的类型或每个值的类型。 例如,在下面,我没有具体说明字典类型: let monthDaysDictionary = [“一月”:31,“二月”:28,“三月”,31,“四月”:30,“五月”:31,“六月”:30,“七月”:31,“八月”: 31,“ […]
“泛型编程 是一种 计算机编程 风格, 其中 算法 是根据 类型 编写的 待定,然后 在需要作为 参数 提供的特定类型时实例化。” — Wikipedia 使用泛型编写代码是一种编写函数和数据类型而无需指定需要使用哪种确切类型的方法。 顾名思义,泛型类型不是特定的。 通过使用泛型,我们可以编写非特定的代码,因此,我们可以以更清洁,错误更少的复杂方式抽象代码。 在上一篇文章中,我描述了数组,字典和可选变量是泛型的示例。 在第二部分的文章中,我将讨论编写通用数据类和结构,编写通用函数和约束通用类型。 第三部分将讨论关联类型和通用Where子句。 编写通用数据类和结构 虽然数组,字典和可选变量都是泛型的示例,但我们也可以使用泛型来创建自己的数据类型。 例如,我可以堆一个 具有泛型的数据类型-不特定于任何数据类型(浮点数,双精度数和整数)。 堆栈使用LIFO(后进先出)过程,将新项目推到堆栈顶部,然后从堆栈中取出最新项目。 我喜欢将其视为一叠纸牌,将它们一叠放在另一叠上,并且只能从顶部取出。 假设我要创建自己的堆栈。 我可以使用尖括号将其指定为通用,这意味着,我可以在创建堆栈时决定要堆栈的内容。 在这种情况下,我想编写一堆字符串,这些字符串代表我当前正在阅读的所有编码书。 1:我创建一个结构来表示我的EricasStack数据类型。 请注意,在尖括号之间使用“通用 ”一词。 我可以在那里写任何词(也许是“炸玉米饼”?)作为我在此EricasStack中使用的值的占位符。 2:我创建了一个泛型数组,该泛型将容纳我的编码书籍堆栈。 3: 我想一次将两本书添加到我的书架中,所以我编写了一个推入两个项目的函数。 4:我想一次将两本书移到我的书架中,所以我编写了一个函数,该函数返回要被POPPED的两个项目。 5:我创建一个类型的EricasStack实例。 请注意,我现在只能追加字符串。 我将两本书推到CodingBooksStack上,然后再推两本书(总共四本书)。 然后,我打印出最终的CodingBooksStack包含的内容。 当我调用.popTwoItems()时,还可以看到打印出来的打印内容。 我也可以赚到一笔EricasStack的钱: 如您在上面看到的,当我创建EricasStack类的实例时,可以用任何类型填充。 编写通用函数 假设我想获取一个Int,然后将其复制到数组中。 假设我想获取一个String,然后将其复制到数组中。 假设我想使用Float,然后将其复制到数组中。 我应该为这三种不同的类型编写三种不同的功能吗? 我可以使用GENERICS编写一个仅适用于所有类型的函数。 函数和方法在泛型类型的上下文中可以是泛型的。 1:我编写了一个名为的通用类型的函数,该函数接受一个项目,并指定一个整数,该整数指定要复制ItemToDuplicate的次数。 2:我创建一个空数组来保存我的arrayOfDuplicates。 3:循环numberOfTimes,每个团队都将一个ItemToDuplicate添加到我的arrayOfDuplicates数组中。 […]
使用元编程和泛型来构建最易于使用的客户端API 该项目的目标是避免通常在客户端应用程序上需要的样板代码。 您将能够避免将本地对象转换为所需的服务器端对象,反之亦然。 您还将免费获得所有服务器通信方法。 只需创建一个新类型并与服务器进行通信即可。 例如,最后,您将能够创建一个符合我们的帮助协议FirebaseFetchable的新类,如下所示: 最终课程宠物:FirebaseFetchable { //来源:忽略 var firebaseId:字符串=“” //来源:忽略 var isCompleted:Bool = false 变量名称:字符串=“” 在里面() {} } 您将能够使用自动生成的PetManager类中的自动生成的方法与服务器进行通信,如下所示: 让fido = Pet() fido.name =“ Fido” PetManager.shared.save(fido) 这会将Pet对象保存到您的远程数据库中。 您还可以自动生成用于从数据库中获取,更新和删除的方法。 因此,实际上这仅是创建新类型matter的问题。 在此项目中,我使用了Firebase,因为它是快速项目的非常简单的设置。 对于元编程,我使用了Sourcery,这是一个出色的代码生成工具。 设定 首先,请在Xcode中创建一个单视图应用程序。 然后,您需要设置Firebase。 转到firebase网站,获取您的plist文件以及仪表板设置。 非常容易和快速。 之后,下载plist文件并将其附加到项目。 如果需要帮助,请查看他们的教程。 然后,创建一个Pod文件,包括Firebase和Sourcery并安装它们。 如果您需要Pod的帮助,请查看此链接。 您的pod文件将如下所示: 目标“您的项目名称” use_frameworks! #Your_Project_Name的广告连播 pod’Sourcery’ pod’Firebase / Database’ 结束 在UIApplicationDelegate中,确保导入Firebase模块: 导入Firebase 并在同一文件中配置Firebase共享实例: func […]
在学习Swift的过程中,我注意到一些函数要求使用Element类型的参数。 我有点被为什么要求我们提供一个类型变量感到困惑 我从未听说过像Array这样熟悉的东西…… 例如,让我们看一下在字符串 数组上调用的append()方法。 当我们使用自动填充来完成append函数时,系统会要求您提供一个参数: newElement:Element。 因为我们已经知道数组包含字符串,所以为什么类型不是String的参数呢? append方法将接受String并打印该方法,并将新字符串添加到Array的末尾。 那么,这是怎么回事? 为什么要求我为该方法提供一个Element,但是它将接受一个String ? 让我们再思考一下数组 。 我们创建的每个数组都有可用的append()方法,但并非所有数组都属于同一类型。 与其在String Array上使用append() ,不如在Int Array上尝试一下。 真好! 即使我们的数组类型从[String]更改为[Int],我们也可以使用Element类型来传递String或Int参数。 由于数组中各项的类型正在更改,因此使用Element可以根据数组中的内容传递正确的类型。 但仍然..什么是Element ? 这是一堂课吗? 结构? 事实证明,它被称为“通用代码”。 这里直接来自Apple文档: “通用代码使您可以编写灵活,可重用的函数和类型,这些函数和类型可以根据您定义的要求与任何类型一起使用。 您可以编写避免重复的代码,并以清晰抽象的方式表达其意图。”
首先,我们必须承认在设计上不可能使用UITableViewCell而不是UICollectionViewCell,反之亦然。 因此,最好创建一些可以代替这两个类使用的东西。 UIView是一个很好的起点,因为它是UIKit中最通用的UI组件。 屏幕上显示的所有内容都可以使用它来创建。 我们可以将其放在表或集合单元中,作为其他所有内容的容器。 让我们从这个简单的想法开始。 第一次尝试 您可以看到其中具有任何视图的集合单元。 在这里以及我们进一步假设,很容易为表单元格创建相同的版本,并且省略了这种实现而不重复代码并减少读取时间的实现。 尽管单元格变得更加通用,但是这种方法给我们带来了一些缺点: 我们失去了标准单元的重用,需要自己创建视图池。 这意味着使用UIKit库进行代码复制; 使用xib更加困难,因为我们需要将所有内容都嵌入到视图中。 有一个恒定的视图类型,因此我们每次使用视图时都需要强制转换类型。 视图的框架严格限制为与单元格内容相同。 我们将使用Swift Generics对其进行进一步修复。 第二次尝试 作为第二种方法,我们对之前的代码进行了一些更改: 首先,如果我们要使用系统的重用,则单元格内部的视图不应更改。 这意味着我们将该属性标记为常量,并在单元初始化期间创建一个视图。 其次,让我们使用Swift Generics到处都知道视图类型。 现在看起来好多了。 但是我们仍然需要讨论有关从xib加载的大问题。 您通常需要一个xib名称,有时还需要一个束名称(对于框架而言)才能从xib加载某些内容。 如果xib与视图的类存储在同一束中,则xib名称足以加载视图,因为可以使用Bundle(for:Class)方法从该类接收束名称。 这是需要提供名称的协议LoadableFromXib ; 以及从xib文件加载视图的load方法的实现。 现在,在单元初始化期间从xib加载任何视图要容易得多。 看一下LoadableFromXibContentCollectionCell类中的视图初始化: 因此,现在我们可以使用任何视图创建集合(和表)单元,或者使用初始化程序创建它或从xib加载它。 系统对这些单元的重用( 任何视图)都是免费的。 最后,为了使解决方案更通用,让我们在视图中添加插图,因为单元已负责视图的定位和大小调整。 注意,在单元重用期间必须将内容插图恢复为零。 当然,可以向通用单元格添加更多属性,但是看起来contentInsets属性就足够了,因为通用单元格只负责在其内部定位视图。 总而言之,我们创建了具有以下功能的通用单元: 任何视图都可以轻松地转换为表单元格或集合单元,无论它是从xib加载还是以编程方式创建。 例如: SimpleContentCollectionCell -是包含标签的集合单元。 视图填充或边距不会发生变化,因为可以使用像这样的单元格的contentInsets参数来固定它们: cell.contentInsets.left = 20-从左侧增加20个点的插图。 在单元格上设置一些值时,我们确实知道该单元格的视图类型: cell.view.text =“单元格文本” 我已经发布了这篇文章,以分享一些Swift代码中的有用方法。 希望这会有所帮助。 此外,我们非常欢迎您评论和讨论该方法,并在您的项目中使用它。 另外,请随时下载游乐场以显示桌子高亮状态等:Universal Cells游乐场。 […]
我最近使用了map函数,并注意到它的默认返回类型是“ T”。经过一番调查(例如Stackoverflow搜索),我发现“ T”代表一个占位符类型,并且map函数是通用的。 起初,我对自己说“太棒了!”,然后我的下一个想法是“但是,等等,什么是通用函数……🤔”如果您想知道同一件事,请继续阅读! 在分解通用函数之前,让我们首先(简要地)讨论通用代码。 根据Apple的文档,“通用代码使您可以编写灵活,可重用的函数和类型,这些函数和类型可以根据您定义的要求使用任何类型。”您可能熟悉的两个泛型是数组或字典-两种集合类型均允许您可以使用任何类型。 例如,一个字典可能是[String:String]类型,而另一个字典可能是[String:Double]类型。 同样,数组可以是[Int]类型,也可以是[Float]…类型。 按照这种逻辑, 泛型函数是接受任何类型的参数并返回任何类型的函数。 如果您看一下上面的函数,您可能会注意到calculateMinimum函数仅适用于Int类型。 如果我想对Float类型或Double类型使用完全相同的逻辑,则我必须为每种类型创建两个附加函数。 多次重复相同的代码似乎很愚蠢,对吧? 苹果公司也这么认为,这就是引入泛型功能概念的原因。 通用参数和通用返回类型 上面的genericCalculateMinimum函数与calculateMinimum完全相同,但有两个例外。 首先,genericCalculateMinimum而不是接受Int类型的参数并返回Int类型,而是接受类型“ T”的参数并返回类型“ T”。用编写的“ T”告诉Swift,类型“ T”的参数为实际上只是一个占位符类型。 因此,Swift知道在调用函数时根据函数内的输入来推断类型。 例如,如果我们看一下上面的第一个print语句,输入为4和2,Swift推断4和2为Int类型。 由于该函数返回“ T”,因此Swift对参数类型的推断也使其可以返回正确的类型。 因此,在这种情况下,它返回Int类型的值。 在函数内,如果尝试将valueToReturn设置为Bool,则会收到错误消息,因为Bool无法转换为该函数的正确Int返回类型。 同样,Swift从最后一个打印语句推断出参数的类型为String,因此它返回的值为String。 您可能想知道为什么将“ hello”打印为最小值而不是“ yes”。这是因为Swift会根据字符串的哈希值计算字符串的“值”。 根据Apple的文档,“…哈希值是一个Int值,对于所有相等比较的对象来说都是相同的……”用简单的英语来说,哈希值可以比较两个相同类型的变量。 默认情况下,String,Int,Double和Bool类型都可以访问hashValue属性。 查阅Alex的博客,以了解有关哈希值和哈希协议的更多信息。 上面两个函数之间的第二个区别是,genericCalculateMinimum符合Comparable协议。
这是什么? 关于仿制药的另一篇文章? 当然可以。 如果我们要确保只能为某些类型调用此函数,该怎么办? 例如,如果我们只想要Int ,而我们稍后将在代码中进行一些数学运算,该怎么办? 在这种情况下, Protocol即将解救。 现在我们重新营业! 我们现在有信心,您未来的自我不会改变任何事情,并确保您的安全和健康。 感谢过去的自我的关注。 因此,我希望您对Generics如何在Swift中工作有更好的了解。 说到扩展,我们实际上可以扩展Sequence并清理firstIn函数。 干净的代码是不错的代码。
在谈论其他任何事情之前,让我们先回顾一下您的过去。 如何教你和洗脑。 假设您需要打印数组中的每个元素,您可能已经做到了。 let stringArray = [“1”, “2”, “3”, “4”] let intArray = [1, 2, 3, 4] let doubleArray = [1.1, 1.2, 1.3, 1.4] 好吧,让我们打印。 func printStringFromArray(a: [String]) { for s in a { print(s) } } func printIntFromArray(a: [Int]) { for i in a { print(i) } } func printDoubleFromArray(a: [Double]) { for d […]