Tag: 快速

使用带有下标的POP(面向协议的编程)的正确方法。

下标用于使用索引快速访问集合,序列和任何其他可迭代类型。 也就是说,您可以通过索引要更改的集合来获取和添加项。 下标的核心是主要索引没有其他功能的集合。 您可以快速阅读有关下标的更多信息 。 从上一张图片中,我决定让我的容器通用,以确保我所有集合的特定功能。所以我们在这里要做的是创建一个通用容器 ,该容器可以管理或协调如何访问或计算集合项( 项 )。 您可以在其中通过为容器的私有项编制索引或使用添加和获取功能来对容器进行下标。 在下面的示例中,您可以通过对项目进行下标或使用添加的功能get和add函数来访问该项目。 采用这种方法可以避免开发人员跨代码库编写冗余的业务功能。 而是创建特定于您的收藏的东西。 谢谢。

构建轻量级功能标记系统

借助基于枚举的功能标记系统,可以放心地将代码交付生产 在构建应用程序时,通常有必要将代码运送到App Store,但是您不希望用户使用它,因为它尚未准备好投入生产或打算在特定日期投入使用。 您问为什么还没有准备好代码时将其运送到App Store? 如果您的团队遵循持续的交付流程,通常就是这种情况。 所有新代码都没有功能分支,而是合并到开发分支中并开始构建。 在团队中有多个成员时,您仅需要在功能完整,经过全面质量检查并准备就绪后才能发布功能🐯 让我们谈谈代码👨🏼‍🚀 枚举FeatureFlag:字符串,CaseIterable { 案例功能1 } 扩展FeatureFlag {var isEnabled:Bool { 切换自我{ case .featureOne: 如果isRunningInAppStore(){ 返回假 } 返回featureFlagValue() } } 私用var键:字串{ 返回“ com.companyname.featureflag”。 + rawValue } 私有功能featureFlagValue()-> Bool { 返回UserDefaults.standard.bool(forKey:key) } func enable(){ UserDefaults.standard.set(true,forKey:键) } func disable(){ UserDefaults.standard.set(false,forKey:key) } } 在 这里 查看完整的要点 : 通过使用快速枚举,我们有了一个非常好的API。 在我们的代码库中的任何地方使用它都很容易。 FeatureFlag. featureOne .isEnabled […]

Swift计算的属性

在第一篇文章中,我将介绍计算属性以及如何使用Getters和Setters,以尝试将我在使用Swiftlang功能时学到的东西写在纸上。 计算属性 在跳入之前,需要了解一些重要的事情: 将它们视为一段代码,每次调用它们时都会计算出一个值 计算属性始终是变量(从不常量) 这些类型的属性可以在类,结构,枚举的内部或外部使用 当使用计算属性时要当心,因为它们的值可能在每次调用它们时都会改变。 而且,如果使用了setter,它们可以在其封闭范围内更改任何其他值(更多信息在下面)! 定义计算属性 首先,您必须编写一个变量并显式声明属性的类型,以帮助编译器知道将为其分配哪种类型的值。 不要分配默认值。 而是在类型声明之后打开方括号,然后开始使用吸气剂。 由于变量的值是通过使用setter和getter进行设置和检索的,因此您至少需要在方括号内使用getter,如下所示: 上面的代码中发生了什么: 您可以看到Int类型的计算属性,并且在其括号内,我使用吸气剂返回x + y的结果 一旦计算出的属性被调用,getter就被执行并且变量被赋值给结果 清理注意事项 :只要不实现setter,就不需要编写get {}。 这将加快您的写作速度 让我们谈谈获取器和设置器: 使用get {} get关键字使计算出的属性可读 使用getter可以从计算属性读取数据 在方括号内,编写代码,一旦计算属性被调用,该代码将被执行 访问该属性将执行getter 尝试为计算变量分配一个值。 发生了什么? 您不能将值分配给没有设置器的计算属性。 使用set {} 要了解的几件事: 关键字s et使计算出的属性可写。 没有它,您将收到以下错误: 无法分配值[您的计算属性的名称],它是仅获取属性。 当您为计算的属性分配值时,您正在调用设置器 该值可在设置器的括号内访问 您可以在set关键字后的括号内分配一个本地名称。 该局部变量将传递的值传递给计算属性(如在下例中使用newSalaryPerWeek所示) 如果您未在setter定义中提供分配值的名称,则编译器将自动分配newValue的名称。 通过设置,您可以更改同一作用域中其他属性的值,这是您必须知道链接到计算属性的所有依赖项的原因。 有点令人困惑,但这是计算属性能力的一个很好的例子,如下所示: 为什么不使用setter更改其自己的计算属性的值? 因为我会陷入一个无限循环中,一次又一次地将值分配给它自己。 在家尝试this 让我们将此知识应用于其他几个计算属性,但是这次在Enums / Structs / Classes内部,只是看到没有任何变化: 枚举中的计算属性 […]

在Swift 4中将日期转换为字符串的简单方法

斯威夫特是一门出色的语言。 它相对容易学习并且非常直观。 虽然有些事情不是那么简单。 例如,如果您想将数字转换为字符串,则有很多方法。 字符串(数字) “\(麻木)” 但这不适用于日期。 您可以通过调用Date()获得当前日期,但是如果您想填充一个需要字符串的核心数据对象,该怎么办-但您仍然想显示一个日期呢? 如果您想以可读格式输入日期怎么办? 您需要使用日期格式化程序,将其转换然后输出一个字符串。 我一遍又一遍地做这件事,直到我决定创建一个非常简单的函数为我做。 因此,我可以再次将其发布到这里,但这意味着在搜索解决方案时在页面上迷路的任何人都可以使用它。 func formatDate(_ dateString:Date)->字符串{ 让dateIn = dateString 让dateFormatter = DateFormatter() dateFormatter.dateStyle = .medium dateFormatter.timeStyle = .short dateFormatter.locale =语言环境(标识符:“ en_GB”) 返回dateFormatter.string(from:dateIn) } 只需将该函数放在所需的快捷页面中,然后调用它即可。 您可以在参数字段中使用Date()来获取当前日期或以日期格式传递任何日期。 让dateString = formatDate(Date()) 然后它将输出一个可以使用的字符串值。 该方法以编码格式编写,因此,如果要将其更改为长,短或无时间/日期,只需更改函数中的dateStyle和timeStyle元素即可。 如果您需要多次日期转换,则甚至可以在参数中传递这些参数来设置它们。 func formatDate(_ dateString:Date,dateStyle:DateFormatter.Style,timeStyle:DateFormatter.Style)->字符串{ 让dateIn = dateString 让dateFormatter = DateFormatter() dateFormatter.dateStyle = dateStyle dateFormatter.timeStyle = timeStyle […]

应用启动时间:提示和技巧

让我们这样说。 您会看到一个销售良好的应用程序,显然在Appstore中带有一个视频。 您决定安装它。 安装成功。 单击Appstore中的“打开”按钮,或从iPhone / iPad的跳板中单击该应用程序。 至少15秒钟没有任何显示。 结果? 即时卸载。 您的想法,用户会坚持吗? 没门! 人们非常忙,以至于迫不及待地想看到一个很棒的应用程序。 不要因为发布时间而让我谈论他们发表的评论。 真的,人们这样做吗? 是的,他们有。 在我的iOS职业生涯的早期,即使我认为如果人们喜欢该应用程序,他们也会等到该应用程序的主屏幕出现。 他们可能会这样做,但是我们期望这些用户提供的体验每天都在恶化。 我们不希望这种情况在我们的应用程序中发生。 这导致了主题,即应用程序的启动时间。 用户从跳板上单击应用程序图标和启动时间会有时间延迟。 此处的缩放动画渲染花费时间。 即将在iOS中启动类型。 有两种类型。 热启动 这是当您的应用程序出现在iPhone中而不是首次启动时。 这意味着将附加某种缓存。 冷启动 这是当您重置iPhone然后首次启动该应用程序时。 从用户角度来看,冷启动更为重要。 这是用户首次看到该应用程序的地方。 首先是第一件事。 让我们看看您的发射时间是多少。 1:转到“编辑方案”,并将此环境变量DYLD_PRINT_STATISTICS添加为值1。 2:现在运行您的应用程序,您将看到类似下面的内容 总的预维护时间是应用程序的确切启动时间。 如果您可以将此时间减少到大约400毫秒,那就更好了。 您想减少启动时间的提示 1 :附加较少的嵌入式库。 删除那些在应用程序中根本不使用的dylib。 嵌入式库越多,即使在调用applicationDidFInishLaunching之前,系统也将花费更多时间将它们加载到内存中。 除此之外,开始使用静态档案。 2 :减少C ++虚函数 尝试减少C ++虚拟函数,因为它会占用更多时间启动应用程序。 3 :使用Swift Swift代码生成比Objective C更好。 在您的应用程序中使用Swift结构将有助于减少启动时间。 (这就是苹果所说的) 4 […]

高阶函数(Swift):

高阶函数是迅速进行功能编程的概念。 听起来很复杂,但相反却很简单。 定义:可以接受函数或闭包作为参数或返回一个函数/闭包的函数称为高阶函数。 有许多高阶函数,我们将研究其中最广泛使用的一些函数:map,flatMap,filter,reduce和sorted。 返回一个数组,其中包含将给定闭包映射到序列的元素上的结果。 进口基金会 让数组= [1,2,3,4,5] // map使用一个参数关闭,并将更改逐一应用于数组的每个元素。 让mapArray = = array.map({num in 数* 100 }) 打印(mappedArray) //使用尾随闭包来简化地图 让mapArray = array.map {$ 0 + 5} 打印(mapArray) 宣言: func flatMap (_转换:(Self.Element)抛出-> SegmentOfResult)重新抛出-> [SegmentOfResult.Element] whereSegmentOfResult:Sequence FlatMap非常喜欢Map,但是顾名思义,它可以使结果变平,因此,如果您有array(嵌套数组)的数组,并且使用了flatmap,那么它将提供合并了嵌套数组所有元素的级联数组。 进口基金会 让数组= [[“ Dhoni”,“ Ganguly”],[“ Kohli”,“ Rahul”],[“ Yuvraj”,“ Rohit”,“ Bhumrah”]] 让flatmap1 = array.flatMap {$ 0} 打印(flatmap1) 让arr = [“ […]

ARC如何快速工作

在开始示例之前,我想分享一些方法,通过在实例上调用它们,实例的保留计数增加或减少。 我将向您展示自动引用计数工作的示例。 这里的示例从Owner类开始。 其中具有存储的属性,即名称。 下一个代码段定义了Owner?类型的三个变量。 您已经创建了一个新的Owner实例,并将其分配给owner1变量: 现在,已将新所有者实例分配给owner1变量,现在从owner1到新Owner实例都有很强的引用。 因此实例引用计数将为1。 如果将同一Owner实例分配给另外两个变量,即owner2,owner3。 建立了对该所有者实例的两个更强引用: 现在,对该单个Owner实例有3个强引用。 如果要取消分配Owner实例,则需要删除对该实例的强引用。 注意:当实例引用计数达到零时,该实例将从内存中取消分配。

SmallSwiftTips#01:使用分组对元素进行分组:

对于第一个SmallSwiftTips,我将从一个非常方便的新Dictionary init开始,它是init(grouping:by:) 这个新的init是在Swift 4上引入的,它有助于创建一个新的分组Dictionary 。 它需要一个Sequence和一个闭包作为输入。 请注意,此新Dictionary的关键字将是闭包的结果。 在第一个示例中,闭包的结果为Character ,因此我们将有一个新的[Character: [String]]字典。 在第二个示例中,闭包的结果中有一个Bool值,为我们提供了一个新的[Bool: [String]] 。 您也可以使用一系列自定义对象。 此代码将返回一个非常方便的新[AssetType: [Asset]] 。 这可能会很有帮助,希望您喜欢并使用它。 😁🚀

Swift Universe中的迭代器设计模式

(本文最初是用俄语撰写的,并在此处发布。) 迭代器是设计模式之一,通常不为程序员所注意,因为其实现细节通常嵌入在编程语言的标准库中。 但是,它也是四人帮经典著作“设计模式:可重用的面向对象软件的元素”中描述的行为模式之一。 它的理解永远不会被淘汰,甚至可能会有所帮助。 迭代器是一种提供对复合对象的所有元素(通常是容器类型,例如数组和集合)的串行访问的方法。 语言内置资源 创建一个数组: 让numbersArray = [0,1,2] …并循环遍历: 代表numbersArray { 打印(数量) } ……这是很常见的事情,尤其是对于像Swift这样的现代编程语言而言。 但是,此功能由实现Iterator设计模式基础的代码支持。 在Swift中,一种类型必须符合Sequence协议才能被for循环迭代。 除其他事项外,此协议要求具有关联的Iterator类型(必须符合IteratorProtocol )并实现结构方法makeIterator() (此类型返回此类型的特定迭代器): 协议序列{ relatedtype Iterator:IteratorProtocol func makeIterator()-> Self.Iterator //另一个要求在这里… } IteratorProtocol包含唯一的方法— next() ,该方法按顺序返回以下对象: 协议IteratorProtocol { 关联类型元素 变异func next()-> Self.Element吗? } 感觉好像很多复杂的代码,但实际上并非如此。 我们将在一段时间后确定。 例如, Array转换为Sequence (虽然不是直接,但通过协议继承链: MutableCollection继承自Collection ,而Collection继承自Sequence ),这就是为什么可以通过for循环来标识其实例的原因。 用户类型 如果我们的类型必须是可迭代的,我们该怎么办? 像往常一样,显示示例更容易。 让我们定义用于存储书本的书架的类型: 结构书{ 让作者:字符串 让标题:字符串 } […]

弱者和无人者之间的区别迅速。

为了避免保留周期,我们必须指定两个对象之间的关系,即弱,无主,强 默认情况下,对实例的变量引用是强引用。 但这并不总是您想要的。 如果强引用不适合,则您可以使用其他选择,即弱引用和无主引用。 虚弱或无主的实例引用计数增加了。 弱 让我们形象化。 弱总是声明为可选的。它可以包含nil或实际类型。 弱引用的值需要先包装才能访问。 何时使用: 当您不确定实例在整个生命周期中将始终存在时。 例如: 弱所有者不会确定实例将始终存在。 因为在任何时候它都会包含一个实际值或nil。 为了避免代码崩溃,请确保使用guard语句确保捕获的实例永远不会为零。 无人 让我们形象化。 无主总是具有实际类型。 您可以直接访问无主引用的值。 未拥有的引用被释放,它没有设置为nil。 结果,如果对非拥有引用的引用对象进行ac访问, 则会引发致命错误 。 何时使用: 当您确定实例将在整个生命周期中始终存在时。 如何使用 : 例如: 无主拥有者确保实例在clouser中将始终存在。 如果所有者实例被释放,我们的代码将崩溃。 因此在使用无主物品时要小心。 在下一篇文章中,我们将看到Swift内存管理-自动释放池 https://medium.com/@shantakokateit/swift-memory-management-autorelease-pool-eea16d3863eb