Tag: 编程

iOS开发基础:变量2,常量,集合

因此,上一次,您在Swift中创建了第一个程序(恭喜got),并且了解了什么是变量以及如何使用它。 今天,我将向您解释我们知道哪些变量,什么是常量以及我们如何使用它们。 首先让我们谈谈变量和常量之间的区别。 简而言之:变量可以更改或更好,可以更改而常量不可以。 当您要存储可以更改的消息(例如上次)时,可以使用变量,因此不需要很多不同的变量,只需为其分配一个新值即可。 你知道怎么做对吗? 无论如何,为了安全起见,让我们再次看一下。 var message =“某些消息。” 简单的东西吧? 右🙂 但是,当您要存储值并保护其不被更改时,您会怎么做。 假设您要存储一个日期,例如生日。 在这种情况下,您可以使用一个常数。 要声明一个常量,可以使用let (对于变量,请使用var )一词,它看起来像这样: let Birthday =“ 1990年8月1日” 现在,您创建了一个不可改变的常量。 如果尝试为它分配这样的值: 生日=“ 1989年5月23日” 它将返回错误消息:“无法分配值:“生日”是“ let”常量。 也许您在问自己,但是如果var“更好”,为什么我们需要这个,这取决于情况。 稍后您会看到有时保护一些数据不被写入会更好,这就是为什么要使用常量的原因。 好的,现在我们把这部分弄清楚了,让我们看看我们知道哪种类型 。 种类 串 您已经知道什么是字符串 ,您之前使用过吗? 所有用双引号引起来的值的变量都称为字符串 。 如您所知,字符串可用于保存文本数据。 字符串可以被修改,转换并可以保存许多类型的值。 例如,您可以使用+运算符连接多个字符串: 让名称=“杰克” 让姓=“迈克尔斯” 让生日=“ 1700年1月10日” 哇,这家伙老了😀 那么,如何才能将他们团结在一起? 像这样: 让combinedString =“你好,我的名字是” +名字+“” +姓氏+“,我出生于” +生日 这将打印出来(稍后我们将进行介绍): “你好,我叫杰克·迈克尔斯,我在1700年1月10日感到无聊。” […]

Swift 5和ABI稳定性-最佳迁移时间

Swift是一种快速,安全且有趣的语言,具有充分的堆栈潜力和强大的社区支持,可以进行编码。 据Apple称,它比Objective-C快2.6倍,但是,一些研究表明,两者之间的差异并不大。 Swift代码更容易维护,因为没有单独的接口和实现文件,语法较短,并且该语言支持动态框架。 该语言已显着发展,并已被众多开发人员采用。 根据StackOverflow开发人员调查2018,它是第六受欢迎的语言 。对于仅在2014年发布的一种语言,采用率是惊人的。 这些是Swift的一些优点,现在让我们从开发人员的角度来看这些缺点。 Swift仍不成熟,就像一个移动的目标,每个新发行版都引入了重大更改。 许多开发人员指出的关键问题之一是缺乏与较旧语言版本的向后兼容性以及版本锁定,这意味着整个项目及其外部依赖项中只能有一个Swift版本。 因此,如果开发人员想要切换到最新的Swift版本并更新其外部依赖关系,则被迫完全重写其项目。 对于开发框架的开发人员,他们必须为每个新的Swift版本更新其框架,并且不能将其作为二进制预编译框架进行分发。 幸运的是,Swift团队和开放源代码社区正在努力解决此问题,并有望在Swift的下一个主要版本(即Swift 5.0)中解决此问题,自Swift 3.0以来,Swift已向前推进。 ABI稳定宣言指出,他们的目标是: 源代码兼容性,这意味着较新的编译器可以编译用较早版本的Swift编写的代码。 这将删除Swift中当前的版本锁定。 二进制框架和运行时兼容性,从而可以以二进制形式分发框架,该框架可在多个Swift版本中使用。 二进制框架兼容性将通过稳定模块文件的模块格式稳定性来实现,该模块文件格式是编译器对框架公共接口的表示,而ABI稳定性使应用程序和使用不同Swift版本编译的库之间具有二进制兼容性。 在运行时,Swift程序二进制文件与其他库和组件进行交互。 应用程序二进制接口是独立编译的二进制实体必须遵循的规范,才能链接在一起并执行。 这些二进制实体必须在许多底层细节上达成共识,例如如何调用函数,内存中的数据表示,甚至它们的元数据在哪里以及如何访问它。 ABI稳定性意味着将ABI锁定到将来的编译器版本可以生成符合稳定ABI的二进制文件的程度。 一旦ABI稳定下来,它就会在平台的整个生命周期中持续存在。 ABI稳定性仅影响外部可见的公共接口和符号的不变性。 例如,只要保留公共接口,以后的编译器就可以自由更改内部函数调用的调用约定。 类型(例如结构和类)必须具有针对该类型实例的已定义内存中布局,并共享相同的布局约定。 类型元数据被Swift程序广泛使用。 此元数据必须具有定义的内存布局,或者必须具有一组定义的API来查询类型的元数据。 库中的每个导出或外部符号都需要一个唯一的名称,二进制实体可以同意该名称。 Swift提供了函数重载和上下文名称空间(例如模块和类型),这意味着源代码中的任何名称都可能不是全局唯一的。 唯一名称是通过称为名称修饰的技术产生的。 函数必须遵守调用约定,这涉及诸如调用堆栈的布局,保留哪些寄存器以及所有权约定之类的事情。 Swift附带一个运行时库,该库处理诸如动态转换,引用计数,反射等操作。编译的Swift程序对该运行时进行外部调用。 因此,Swift运行时API是Swift ABI。 Swift随附一个标准库,该库定义了许多常见的类型,结构和操作。 为了使出厂的标准库能够与用不同版本的Swift编写的应用程序一起使用,它必须公开一个稳定的API。 因此,Swift标准库API是Swift ABI,以及它定义的许多类型的布局。 所有这些任务已由Swift核心团队完成,但尚未在GitHub上发布。 通过查看任务的状态,我们可以放心地期望Swift的下一个主要版本是ABI稳定的。 因此,一旦宣布Swift是ABI稳定的,此后编写的代码将与该语言的新版本兼容,并且开发人员在迁移到新版本的Java时不必更新项目的所有外部依赖项。迅速。 一旦实现了模块格式的稳定性,库作者就可以将其框架作为二进制框架提供。 由于可以在操作系统内合并稳定的Swift运行时,因此应用程序包的大小将减小。 语言将不断发展,但从那时起对ABI的更改将是可加的。 当最低目标Swift版本支持它们时,可以利用ABI附加更改,因为ABI稳定性仅锁定外部可见的公共接口和符号。 较新的编译器可以进行内部更改,以提高效率。 Swift显然是Apple生态系统中发展的未来,一旦稳定了ABI和模块格式,该语言将摆脱最大的劣势。 请仔细阅读本文,以了解2019年Swift和Objective-C之间的详细比较。 如果您希望将Objective-C代码库转换为Swift,那么现在是开始的最佳时间。 我写了一篇文章,内容涵盖了从SVProgressHUD到IHProgressHUD的转换,该文章完全是用Swift编写的,具有线程安全性,并且具有与使用Swiftify for Xcode的SVProgressHUD相同的API设计。 https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.md […]

谈论我的泛型-第二部分(快速3)

“泛型编程 是一种 计算机编程 风格, 其中 算法 是根据 类型 编写的 待定,然后 在需要作为 参数 提供的特定类型时实例化。” — 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数组中。 […]

WinAPI IOCP编程:可扩展文件I / O

在本文中,您将简要了解I / O完成端口(IOCP),以及通过使用I / O请求复制带有文件的文件夹的简单C ++实现。 我们希望本指南对具有C ++和Windows API基本经验的人有用,并能帮助他们学习WinAPI IOCP编程的基础知识和某些特定知识。 总览 I / O完成端口是使用较早分配的线程池来处理多个I / O请求的灵活方式。 而且,它们可以避免由于切换上下文以及工作线程太多或太少而导致的性能损失。 队列内核对象位于IOCP的基础上,该对象用于存储I / O完成数据包。 尽管数据包按照FIFO顺序放入IOCP队列中,但可以按照其他顺序取出。 创建IOCP并将其与文件句柄关联是通过CreateloCompletionPort API函数完成的: HANDLE WINAPI CreateIoCompletionPort( _In_ HANDLE FileHandle, _In_opt_ HANDLE ExistingCompletionPort, _In_ ULONG_PTR CompletionKey, _In_ DWORD NumberOfConcurrentThreads ); 阅读全文:WinAPI IOCP编程:可扩展文件I / O 撰写人: 安德鲁·季莫申科 Apriorit的软件设计师

IBM通过Swift获得成功

IBM因成为技术领域笨拙的老人而臭名昭著。 它们已经存在了很长时间,并且(不包括IBM Watson)在寻求可以迎合时代精神的新创新方面一直落后于他们。 随着IBM最近为Swift推出的IBM Bluemix Runtime(IBM的多面云平台即服务),他们证明了他们的确表明自己确实可以变得肮脏不堪,并与我们那些ra脚的年轻人混在一起。 对于那些不熟悉的人,Swift是苹果的宝贝。 这是他们为macOS,iOS,OSOS开发的编程语言,基本上就是您可以想到的任何现代Apple OS。 简洁,自然的语言特性使它在编码社区中大受欢迎,尤其是对于那些有志于为Apple OS做出任何贡献的人(移动开发人员,我在看着你!)。 它适用于客户端和服务器端开发,需要较少的内存使用,并且总体上减少了硬件磨损,所有这些都导致了一种编码语言,使每个人的生活变得更加轻松。 苹果公司使学习变得简单(和FuN !!!),使Swift更具吸引力。 以iPad上的Swift Playgrounds应用程序为例,在该应用程序中,用户可通过围绕一个谜题的小头像来学习如何使用Swift。 可爱。 如果您在Quora,Medium或Twitter上关注我,那么您可能已经注意到我是Swift的忠实粉丝: 最初发布在 DamianEsteban.com

Swift 3中的错误处理:尝试,尝试?和尝试!

某些人可能已经熟悉使用关键字try来处理Swift中的错误。 对于那些不知道try是什么的人, try只是一种处理任何给定函数中可能出现的错误的方法。 通常,我们具有“抛出”功能,这意味着它们具有抛出错误的能力,而try是一个简洁的关键字,它使我们能够处理那些错误的可能性。 在构建我们的应用程序时,可以使用三种try形式。 尝试 尝试? 尝试! 如果您对这些变体感到恐惧,那就不要! 而且,如果您不确定要使用哪一个,请不要担心,我已为您覆盖。 正如我之前提到的, try通常与throw函数结合使用,因此我们将讨论一下throw函数,并在实际中使用try关键字。 假设我们正在尝试通过一些JSON进行解析,以便可以将这些数据带入我们的应用程序。 此数据可能由于互联网中断而无法到达我们的应用程序,或者您尝试提取的数据不再存在! 这些都是在我们尝试从API检索数据时可能出现错误的情况。 但是Swift的JSONSerialization方法具有内置函数,默认情况下throws 。 Swift知道我们检索数据的尝试可能会带来一些错误,并创建了一个函数,该函数使我们能够在发生错误的情况下解决该情况。 使用try ,我们的throw函数必须包装在do-catch语句中。 这使我们能够自定义错误处理并根据错误执行特定的操作。 下面我们将使用try来优雅地捕获任何错误。 做{ 让responseJSON =试试JSONSerialization.jsonObject(with:data,options:[])as! [[String:Any]] 完成(responseJSON) } { 打印(“嗯,这里出了点问题。请尝试连接到wifi。”) } 作为开发人员,将try与do-catch语句一起使用可使我们检查有意义的错误,以样式处理它们,并避免用户感到沮丧。 考虑一下,我们是否真的希望我们的应用程序在用户没有任何互联网连接时崩溃,还是我们要让他们知道该应用程序一旦连接到wifi就会继续运行? 在这种情况下,通知会更有帮助,而我们的do-catch语句使我们可以做到这一点。 另一方面,我们也可以使用try?处理错误try? 。 如果您有使用可选控件的任何经验,那么您很快就会意识到该try? 就是这样。 try? 让我们忽略我们的错误,并在我们的函数将其抛出时让它们变为nil。 因此,我们不必将代码包装在do-catch语句中。 但是,如果要分配try?我们是否必须解开变量try? 有价值。 让responseJSON =试试吗? JSONSerialization.jsonObject(with:data,options:[])as! [[String:Any]] 如果让responseJSON = responseJSON { print(“是的!我们刚刚包装了responseJSON!” } 上面的代码为responseJSON分配了一个可选值,并在调用的函数引发任何错误时将其设置为nil。 使用try? […]

大中央调度-Swift 3

Grand Central Dispatch或GCD是一种在我们的iOS应用程序中处理多任务的方法。 该系统的工作方式是可以将许多任务发送到调度队列,而调度队列又将在多个线程上运行,并最终由系统进行管理。 当我们尝试在其中一个应用程序中更新UI时,常常会想到GCD。 这些更新发生在主线程上,但是我们可能需要执行其他任务,并且这些任务可以在并发线程或后台线程上运行。 要添加一些上下文,队列是可以在主线程或后台线程中同步或异步运行的代码块。 使用队列时,我们可以使用Apple提供给我们的全局队列,也可以创建自己的自定义队列。 应该注意的是,全局队列应该谨慎使用,因为我们不想滥用它们。 为了更好地理解其中一些概念的含义,让我们直接进入代码并创建队列。 let queue = DispatchQueue(标签:“ queue.1”) 在这里,我们创建了一个自定义队列,并为其分配了唯一的标签。 您所说的标签完全是任意的,但最好为其命名与您的应用相关。 我们可以在这些队列上调用不同的方法,例如异步与同步。 这些关键字将告诉我们的应用程序如何执行我们的代码。 这是我们的代码在后台线程上同步运行而在主线程上运行的代码的示例。 //后台线程 queue.sync { 对于i in 0 .. <10 { 打印(“🔷”,i) } } //主线程 对于20中的i。<30 { 打印(“⚪️”,我) } 如果运行此代码,我们将看到如下所示: //打印:🔷0🔷1🔷2🔷3🔷4 … ⚪️20⚪️21⚪️22⚪️23⚪️24 … 我们的程序将在主线程上运行的for循环处停止,因为它是同步的,因此它可以在队列中执行我们的代码块。 如果我们将队列更改为异步,我们的应用程序将可以在主线程上自由运行代码,并且还将同时在队列中执行代码块,因此我们得到如下信息: //打印: 🔷0⚪️20🔷1⚪️21🔷2⚪️22🔷3⚪️23🔷4⚪️24🔷 … 尽管主线程是应用程序中的最高优先级,但是我们也可以指定队列的重要性,并让我们的应用程序知道如何确定任务的优先级。 该规范称为服务质量 (QOS)。 QOS是一个枚举,我们可以按从最高优先级到最低优先级的顺序将以下值分配给列出的队列。 .userInteractive .userInitiated 。默认 。效用 […]

开始Swift编程第3部分-运算符,可选和Nil值

在上一篇文章中,我们介绍了值类型,引用类型并以集合类型结束。 Swift编程入门第2部分—值类型,引用类型,指针和集合类型 之前,我们讨论过变量,常量和类型。 medium.com 今天,我们仍将继续介绍基础知识,但是好消息是在今天之后,您将能够编写一个解决您的数学问题的程序,无论是幼儿园的数学课程,还是使用公式进行的高级财务计算。 初步资料 您应该了解操作顺序(PEMDAS)的概念 如果数学课对您来说太早了,请按以下步骤操作: 括号(从内到外) 从左到右的指数 从左到右的乘法 从左到右划分 从左到右加法 从左到右的减法 而已! 经营者 只要达到三年级,您就已经在编程中看到了大多数操作员。 让我们看看您已经知道的那些。 加,减,乘和除的一种简便方法是将运算符追加到赋值运算符(您仍然可以使用加法运算符使用此方法来连接字符串)。 可选值和零值 好的,我将尝试使其变得容易,但可能会伤到您的大脑。 很好,这意味着您将学习。 当我谈到变量实例化和声明时,我希望您回想一下本系列的第一部分。 我有点掩饰了声明,而是给了您一些实例化新变量的例子。 我很抱歉,这只是为了让您免于一切,直到您准备好为止。 我们可以像这样声明变量

戴夫·托马斯(Dave Thomas)的数据修补Kata的快速解决方案,第1部分

戴夫·托马斯(Dave Thomas)的数据修补Kata的快速解决方案,第1部分 我正在Swift中解决Dave Thomas的代码问题,并将分享我的思考过程和解决方案。 以下是我对“数据整理” kata [项目回购]的第1部分的解决方案。 挑战在于分析一个混乱的,真实世界的数据集。 在weather.dat中,您将找到2002年6月在新泽西州莫里斯敦的每日天气数据。下载此文本文件,然后编写程序以输出温度分布最小(最大温度为第二列)的天数(第1列)。 ,最小的第三列)。 为了摆脱不需要的列,removeUnneededColumns()在每行上循环并仅保留前三个单元格。 该方法可以正常工作,但是很丑陋,需要改进(有什么建议吗?)。 注意,并非我们的所有数据点都是“干净的”,有些包含垃圾信息,例如“ *”。 为了在cleanData()中解决此问题,我们创建了一组无效字符并将其删除。 让invalidCharachters = NSCharacterSet(charactersInString:“ 0123456789。”)。invertedSet 要注意的另一件事(我在此kata之前就很模糊)是,当您在Swift中嵌套了高阶函数时,就无法使用简写语法(例如array.map {$ 0 * 2}),您需要列出参数并使用“ in”关键字 气象记录评估员 现在,我们已经加载了数据,对其进行了整理,对其进行了清理,并将其转换为WeatherRecords数组,我们需要找到温度变化最小的日期。 由于WeatherRecord结构具有计算的属性temperatureDelta: var temperatureDelta:Double { 返回maximumDailyTemperature — minimumDailyTemperature } 我们需要做的就是遍历记录并找到增量最小的记录。 minElement()方法将执行此操作(请注意,由于我们不使用嵌套闭包,因此我们将返回使用更简洁的$ 0,$ 1语法)。 执行者 现在,我们拥有解决此kata所需的所有组件,我们只需要将它们放在一起并获得正确的答案。 我们将使用一个Executor结构来执行此操作,该结构使用先前方法的输出来调用每个方法并返回答案。 execute()的单元测试还充当集成测试,用于验证一切是否按预期进行。 我将在本系列的其他kata后面编写我的解决方案和思考过程。 请让我知道什么有用,什么没用。 另外,我很想听听您关于如何改进代码任何部分的想法。

学习Swift:闭包

嗨,大家好! 我决定我也想发布一些我在编程时学到的概念。 对于那些不知道的人,我是一名软件工程师,目前专注于在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] 让奇数=数字。过滤器{$ […]