这就像老与新,青年与经验之战,父亲与儿子之战。 所有很酷的孩子似乎都喜欢Swift,并且对其周围的炒作非常庞大。 尽管像Crusty这样的年长者和经验丰富的人似乎忠于Objective-C。 那么谁是对的? 而且,更重要的是您应该怎么做? 我决定在一篇文章中汇总所有可用信息,因此无论您是经验丰富的开发人员还是iOS开发的全新人员,您都可以决定。 至少,您了解的越多越好。 初始信息 在WWDC 2006中引入了Objective-C 2.0,但它似乎已经存在了数十年。 最初的Objective-C于1984年首次出现,因此它已有32年的历史了! Objective-C是一种开源语言,主要用于Apple平台(macOS,iOS等)。 根据redmonk.com的研究,Objective-C是第十大最受欢迎的编程语言。 Github的这篇文章表明,2014年它是第9种语言,但在2015年不再排名前10位。 至于薪水,除了qz.com上的这张表,我什么都找不到。 但这真的过时了。 Swift是在WWDC 2014中引入的,在撰写本文时,该编程语言已经有了第3版。 它是开源语言,主要在Apple平台上使用。 由IBM积极传播。 据redmonk.com称,它现在是历史上第17种最受欢迎的编程语言,也是增长最快的语言。 所有新的代码示例都是用Swift编写的,大多数博客作者都使用它。 因此,您可能现在就想:“为什么我要浪费时间阅读本文-我绝对应该学习Swift!”。 我完全同意。 您应该学习它。 但是您应该在下一个项目中使用它吗? 您是否应该忽略Objective-C作为新的iOS开发人员? 让我们仔细看看。 目标C 我将重点关注使用Objective-C并学习它的利弊。 优点: Objective-C是一种成熟的语言,具有庞大的社区,许多经验丰富的开发人员,最佳实践和编码风格。 许多大型项目中都使用了许多经过良好测试的第三方库。 ( 注意:其中一些可能不会更新到最新的iOS版本 ) 有大量的旧代码需要得到支持。 (特别是对于Crusty) 与其他语言的兼容性。 您可以在Objective-C文件内毫无问题地使用C或C ++。 如果需要在Swift代码中使用C ++,则应先将其包装在Objective-C代码中,然后再将其导入Swift中。 缺点: 早晚Objective-C将无法支持某些新功能,因此将有仅Swift标记的方法和框架。 它是一种过时的语言,缺少其他编程语言中提供的许多有价值的功能。 (看看Swift枚举和哭泣) 因此,基本上,如果您已经在Objective-C方面拥有丰富的经验,并且知道一些C / C ++,那么在接下来的5年或至少在苹果成为主要公司之前,您会做的很好。 永远有一个利基为您。 迅速 使用Swift的优点如下: […]
我已经在我的应用程序中使用了很长一段时间(Facebook,Pinterest和Buffer等巨头也使用过Texture)。 这是一个基于UIKit构建的iOS框架,即使最复杂的用户界面也可以保持平滑和响应。 在本教程中,我想分享我在Texture方面的经验以及所有有关如何充分利用此工具的有用技巧。 我们将一起在Texture中实现几个接口,并查看其实际工作方式。 起源 当他们构建Facebook Paper应用程序时,纹理起源于Facebook内部。 作为该项目的首席工程师之一,斯科特·古德森(Scott Goodson)最初从事第一批iPhone构建应用,例如计算器,股票,时钟等。 在理想的世界中,我们希望药丸可以增加数量而无需求助于近似值(例如在指标中显示999+)。 同时,我们希望支持诸如动态类型之类的辅助功能。 解决此问题的最明显方法是使用水平UIStackView并将标签和药丸保留在堆栈中。 不过有一个问题! 在这种情况下, UIStackView 。此外,您还必须设置contentHuggingPriority和contentCompressionResistance并使用其他属性(在读完这句话之后,我需要喝杯咖啡)。 摆弄所有这些属性并弄清楚它们将很容易使我花费一个下午的时间。 相比之下,让我们看一下Texture的实现: 另外,Texture在`ASTableNode`上有一个很好的`inverted`属性,对于聊天/消息应用程序来说真的很方便。 基本上可以确保单元格是反向的,因此它们从底部开始!
方法 自上次以来的变化 上一次基准测试的最大变化是,就像第一次一样,我已经切换回了macOS。 Vapor对Vapor 2.0进行了非常深入和详细的重写,我还通过触摸条将笔记本电脑升级到了2016年底的rMBP。 由于我从未遇到过产生足以进行测试的负载的问题,因此这对结果的影响应该很小。 基准测试 在每个框架的相同软件设计上执行了两个基准测试。 第一个是博客页面的表示形式,第二个是JSON数据。 它们被设计为尽可能地彼此接近,同时仍以每个框架的独特语法和样式进行本地编码。 这些旨在代表您可能会使用服务器端实现的真实场景。 它们足够复杂,不仅可以在屏幕上打印“ Hello,World!”,而且还足够有效。 源代码 与往常一样,所有这些都是通过公开的开放源代码完成的。 如果您想通读代码以了解它们是如何组合在一起的,请查看自上一篇文章以来所做的改进,或者在您自己的环境配置中重复测试,您可以在此处找到完整的源代码: https://github.com/rymcol/Server-Side-Swift-Benchmarks-Summer-2017 笔记 有几件事需要澄清和注意: Kitura和Zewo在过去的建筑物中都存在绝对文件路径中带有空格的问题。 我没有重新测试以查看是否仍然存在,只是在文件路径中没有使用任何空格。 每个框架现在都视为发行版(而非Beta版),这部分是为什么我尚未在Swift 4上进行测试的部分原因。 Zewo是单线程的,旨在以并行配置运行,这意味着计算机上的每个逻辑处理器ID都在运行一个进程。 同样,Node旨在使用群集在多个实例上运行以实现最佳性能,并且已实现。 Perfect,Vapor和Kitura是线程化的,它们管理自己的线程。 所有四个Swift框架均在发布模式下的3.1发布工具链上进行了编译。 节点无法编译。 Node.js包含在当前的稳定发行版中 如果删除任何给定框架的绒毛(功能集),而仅使用骨骼,则可能会得到更快的结果。 这次我没有做任何事情,因为我想在每个框架中进行开发,因为它已经展示出来,并且遇到它的大多数开发人员将如何使用它。 从Vapor 2开始,Vapor不再是纯粹的Swift,至少包括chttp和LibreSSL / OpenSSL。 Vapor具有用于运行发行版的特殊语法。 如果仅执行二进制文件,则将获得一些额外的控制台日志记录,这些日志记录将有助于开发和调试过程。 那有一点点开销。 要以发布模式运行Vapor,您需要添加: –env =生产 到可执行文件。 即 .build / release / Run –env = production 为什么选择Node.js / Express? 我决定将Swift与Node.js中的Express框架抗衡。 […]
你为什么要打扰? 使用DI,您的代码变为: 更容易测试 更容易扩展 易于重用 可可中常见的DI模式: 构造函数注入 在需要时,将依赖项作为对象创建本身的一部分传递给对象。 2.财产注入 通过设置对象状态值或属性传递所需的依赖项时。 3.方法注入 当需要的依赖项通过调用对象的方法来传递时,将根据需要更新对象的初始状态。 可可大量使用所有这三种DI模式。 如果您使用了Storyboards或xibs,则在创建IBOutlet时,它将使用属性注入将它们加载为初始值。 常用的DI反模式: 混蛋注射 控制怪胎 普通DI容器: 界面生成器 台风https://github.com/appsquickly/Typhoon Swift注入https://github.com/Swinject/Swinject
大家好,我想分享一下我遇到的针对开发人员的iOS-9新功能。 正如苹果公司所建议的那样,开发人员要适应最新的技术,这些技术会随着每个iOS版本的变化而变化,以具有更好的性能,并通过WWDC进行演示。 开发人员也对iOS 9感到高兴。 在一长串的改善中,以下是最重要的9项 使用CoreSpotlight的搜索扩展性 Apple归功于CoreSpotlight的重要性不可低估,因为它在iOS 9为开发人员提供的新功能列表中显得很高。 简而言之,CoreSpotLight为应用程序提供了与系统范围的搜索功能集成的方式,并将其内容显示在Spotlight搜索结果,Handoff或Siri提醒中。 此外,由于深层链接,当用户点击搜索结果时,该应用程序将启动,并带有足够的信息以显示该搜索结果最合适的内容。 CoreSpotlight使得深度链接的另一种用法是实现应用程序历史记录。 此功能将使应用程序提供类似于浏览器导航历史记录的历史记录堆栈,并且任何在Search中注册的应用程序都将免费获得它。 CoreSpotlight不仅适用于本机应用程序,还适用于Web应用程序。 特定的标记将允许指示可以通过Spotlight搜索访问网站。 这意味着,当导航到与搜索结果相关的深层链接时,用户将被带到该网站,或者,如果安装了特定应用,则将被带到该应用。 UIKit UIKit在每个iOS应用程序中使用,并驱动用户界面。 在iOS 9中,Apple从根本上改变了开发人员应使用新的UIStackView创建布局的方式。 UIStackView 新的堆栈视图非常重要,因此Apple建议您开始使用堆栈视图构建用户界面,并且仅在界面变得过于复杂或高度自定义时才偏离。 堆栈视图从开发人员那里抽象了很多创建约束的工作。 您将项目插入堆栈视图,UIKit会在运行时自动分配适当的约束。 在界面生成器中可以使用几种方法来使用堆栈视图。 您可以从对象库中选择水平或垂直堆栈视图,也可以使用Xcode底部的专用按钮: UIKit动态 一直很受欢迎,而且很有趣 UIKitDynamics API具有新行为。 除了现在支持非矩形碰撞边界(即路径)之外,还有针对UIAttachmentBehavior的新附件类型的新行为类。 新的行为UIFieldBehavior使开发人员可以对矢量力场进行建模。 苹果甚至提供了一个不错的代码示例来演示如何在此处使用它。 值得下载以查看实际的新行为并查看显示如何实现它的代码示例。 UICollectionView增强功能 自从iOS 6引入以来,集合视图已成为在Cocoa Touch中显示数据列表的首选方法。与表视图相比,它们具有明显的优势,但最大的优点是能够定义自定义布局。 在iOS 9中,它们变得更加强大和直观。 新的布尔属性sectionHeadersPinToVisibleBounds强制流布局像表视图一样始终工作。 现在,在滚动过程中,节标题将停留在屏幕顶部。 它们也可以很容易地重新排序。 如果您使用的是UICollectionViewController ,则将installsStandardGestureForInteractiveMoment设置为true。 现在,只需一行,用户就可以在其用户界面中按自己的意愿订购商品。 UIPickerView增强功能 全世界的开发人员都编写了一些技巧来正确选择选择器的视图。 现在,选择器视图已为调整大小和适应性提供了本地支持。 在iOS的早期版本中,即使您尝试操纵日期选择器和选择器视图,它们也会强制使用默认大小。 这两个控件的默认宽度现在为320点。 以前,这将是显示的iPhone的设备宽度。 很少有人提到最近在NSLayoutConstraint上添加的函数activateConstraints(_ 🙂 。 这是在iOS […]
顾名思义 , NSUserDefaults应该仅用于存储首选项和应用程序设置。 您不应该在其中存储关键数据和/或用户数据。 NSUserDefaults的优点: 易于存储和检索数据。 有助于以最小的模糊度存储默认值 NSUserDefaults的缺点 不适合大数据集 当您尝试存储和加载大量数据时性能下降 全有或全无的方法 CoreData是一个成熟的持久框架,支持大型数据事务。 CoreData允许您构建用于存储用户数据的关系实体-属性模型。 CoreData的优点 可靠的框架进行交互和查询数据 正确设置(具有关系)时可以非常快 强大的功能 CoreData的缺点 需要时间来掌握和学习核心概念 需要适当的应用架构设计才能高效 在改善应用程序的同时,还需要改善数据架构 如果不小心,迁移到新版本可能会很痛苦。
在我开始学习Swift时,June看到我寻求您的帮助。 七月忙于旅行。 现在八月是iOS月。 我很幸运,作为Twilio的开发人员福音工作的一部分是学习新知识。 这就是为什么我在6月参加了Big Nerd Ranch Swift和iOS课程的原因,也是促使我在8月致力于构建我的第一个iOS应用程序的原因。 我的第一个应用 从第一个应用程序开始,我真的是我要从头到尾从空白Xcode项目到App Store的第一个应用程序,全部由我自己承担。 我以前曾在iOS应用程序上工作过。 我记得有一次我在处理iPad应用程序时非常严重地使其崩溃,以至于签出该应用程序的先前版本仍然会导致我花很长时间查看的功能崩溃。 我没有收到太多要在该应用程序上完成的任务。 但是那是内存管理Objective C和团队合作的日子。 现在,凭借对Swift的最新了解,只有我自己,Xcode和一个月的空白空间来构建东西。 2,000,000份申请 当然,人们总是要问的一个问题是,应该做些什么。 这是我的第一个应用程序,并且是一个单独的工作,因此,我正在寻找范围受限的东西,这个月可以实现的东西,我可以实现的东西。 当我想起苹果今年在WWDC上宣布的App Store现在可以下载超过200万个应用程序时,我意识到我并不是在寻找全新的想法。 新手开发人员可以在一个月内完成的所有工作几乎都已经完成。 我认为最好的主意是在不同的环境中解决以前做过的事情。 碰巧的是,我拥有fxrat.es,这是世界上最受欢迎的汇率计算器。 最好的功能不是最新的汇率数据,而是可以在现代浏览器中离线使用。 这是一个我想在国外使用的网络应用程序。 新的和改进的 我一直在考虑重写它,原因有两个。 首先,有时它只是行不通,而且我从未弄清原因。 其次,它当前可使用Web平台的应用程序缓存脱机工作。 由于良好的原因,AppCache即将消失,因此是时候进行更新以使用我最喜欢的新浏览器功能Service Worker了。 但是,这在Safari中不起作用。 在我看来,这是一个很好的机会,既可以重写我现有的网络应用程序,又可以为iOS生成一个新的,具有脱机功能的本机应用程序,我可以在App Store中发布该应用程序。 任务已设定 所以对我来说是八月。 内置于Xcode中,用于创建新的应用程序。 祝我好运,并在GitHub上关注我的进步。 在App Store中见。
扩展,委托,黑盒,覆盖 不要这样 MyViewController类:UIViewController,UITableViewDelegate,UITableViewDataSource,UIPickerViewDelegate,UIPickerViewDataSource {…} 为什么? 这是不好的编码,您可能会继续向MyViewController添加更多的委托类,并使该类变得可怕。 记住规则:模块必须少于400行代码,包括注释。 像这样 制作一个名为MyViewControllerTableExt的新Swift文件,并将其添加 扩展MyViewController:UITableViewDelegate,UITableViewDataSource {…} 制作另一个名为MyViewControllerPickerExt的新Swift文件,并将其添加 扩展MyViewController:UIPickerViewDelegate,UIPickerViewDataSource {…} 为什么? 这些文件的名称将使代码更易于阅读和调试。 在小模块中跟踪错误比千行模块容易得多。 这也是良好的编码习惯。 几个月后,回顾一下代码,您会发现它们仍然易于阅读和维护。 不要这样 从父控制器 self.present(childViewController,animation:true){} 然后从该子控制器中按一个按钮 self.dismiss(动画:true){} 为什么? 这是错误的编码。 父母失去了控制。 它打电话给孩子,直到孩子决定解散自己才知道工作何时完成。 在最坏的情况下,父母可能会叫几个孩子,却不知道哪一个仍在记忆中。 这是不对的。 除非子控件是类似于box的单按钮屏幕,否则不要使用它。 像这样 创建一个名为globalStruct的快速文件,并添加此文件 协议ChildDelegate:类{ func childResult(数据:字符串) } 在子viewController中,添加委托 class ThisChildViewController:UIViewController { 弱var委托:ChildDelegate? … } 当孩子完成工作后,将控制权和数据传回给父母,然后它将做 自委托。 childResult(结果); 请注意, 孩子不会调用self.dismiss。 然后从父目录创建一个名为MyViewControllerChildExt的新Swift文件,并执行以下操作 扩展MyViewController:ThisChildDelegate { func childResult(data:String){ self.dismiss(animated:true){//父级在其控件中关闭子级 […]
我最近使用了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协议。
2018年7月24日 因此,如果您已打开本文,则可能要尝试为使用其他Cocoapods的Cocoapods创建一个库。 原则上看似简单,但实际上没有官方方法可以做到。 实际上,只有通过分散的StackOverflow帖子和Github问题,我才能弄清楚。 好了,不再! 本教程旨在成为有关如何创建使用其他Cocoapods的Cocoapods的综合教程(多达您想要的!) 旁注 :如果您只想看工作代码,可以在我的Github上找到最终产品 所以首先,您显然需要安装cocoapods。 打开终端(您将经常使用它)并在下面的命令中输入。 sudo gem install cocoapods 注意:如果出现此错误: ERROR: While executing gem … (Gem::FilePermissionError) You don’t have write permissions for the /usr/bin directory. 尝试以下方法: sudo gem install cocoapods -n /usr/local/bin 如果以上命令永远存在,请使用–verbose标志运行它。 这样一来,您可以看到它挂了什么。 sudo gem install cocoapods -n /usr/local/bin –verbose 另请注意:根据您计算机的处理器/功能,以下所有命令似乎永远都用不完 。 这就是为什么我建议在每个命令中添加–verbose标志的原因。 (个人而言,我使用的是2011 Mac Mini,每个命令至少需要半分钟。是的,慢速折磨☹️) 无论如何,现在我们已经安装了Cocoapods,是时候创建pod了。 我们将使用名为pod lib […]