Tag: swift

为什么我停止使用情节提要和Interface Builder

在开始点燃手电筒之前:是的,我以前曾经广泛使用过Interface Builder。 实际上,直到几个月前,如果没有我心爱的情节提要,我无法想象创建一个项目。 我研究了一些代码约束,而仅语法本身就使我不寒而栗。 因此,当您在Samsao的第一天得知我的指南明确禁止使用Interface Builder时,您可以想象到我的惊讶。 当我的同事开始解释这是为什么时,我所能想到的就是:但是使用IB变得如此简单! 然而,放开情节提要几周后,我无法想象自己会再使用一次。 现在,如果您是IB的狂热分子,您可能会将我钉为极端主义者,而无视此刻我所说的一切,那很好。 但是,如果您可能想知道是否有办法让您每天花30分钟等待重载的故事板文件打开,那么这篇文章适合您! 因此,不要浪费您的宝贵时间,让我们开始吧! 他们很慢 如果您有足够的耐心并且喜欢在等待IB文件打开时进行呼吸练习,那么对您来说非常好! 就个人而言,每次我尝试打开一个故事板时,我要做的就是把头撞在墙上。 我知道,我的耐心正在发展中。 在团队合作中与他们共事 如果您是自由职业者/独立开发人员或将来的开发人员,那么这可能还没有影响到您,但是如果您曾经不得不处理NIB文件上的合并冲突,那么您会感觉很糟糕。 使用UI代码,轻而易举! 它们使代码的可重用性复杂化 在代码中,如果有5个看起来几乎相同的屏幕,那么使用协议在它们之间高效地重用UI代码非常容易。 使用情节提要,祝您好运,找出如何分享观点和行动! 他们会变得很乱 一个图像说出一千个单词。 这到底是怎么回事? SnapKit 使编写代码约束变得如此轻松! 好的,您已经阅读了有关Visual Format Language的一两本书,这让您有些哭泣…… customView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat:“ V:| -20- [customView(> = 70 @ 500)]-[customView(== customView)]-30- [customView]-|”) 但是,如果您了解SnapKit及其简单性,您真的没有任何借口! customView.snp.makeConstraints {(make)in make.top.equalToSuperview() make.centerX.equalToSuperview() make.width.equalTo(70) make.height.lessThanOrEqualTo(200) } UI代码没有比这更好的了! 总结一下 是的,对于初学者来说,情节提要更容易进入,对于快速制作原型非常有用。 但是,如果您从事的是大型专业项目,那么我实在找不到一个很好的理由来说明为什么有人会喜欢使用它们而不是用代码编写UI。 如果您对如何使用SnapKit设置没有情节提要的项目感到好奇,请查看有关此内容的新博客文章! 现在,我知道那里的大多数IB / storyboard狂热者仍然认为我很疯狂,如果您是其中的一员,我很想得到您的意见,请给我评论! […]

深入了解Xcode的代码段库

作为开发人员,一种常见的做法是一次又一次地编写相同的代码。 我们每天都会编写数百行代码,其中一些代码需要我们编写和重写,因此会花费大量时间。 无需复制代码或重写代码,我们可以使用代码片段库— Xcode(IDE)中存在的有用且有价值的功能。 总览 代码段是一项非常有用的功能,它使我们可以保存我们经常编写/使用的一段代码,并创建一个快捷方式来重用项目中其他地方的同一段代码。 Xcode的代码片段库仅包含少量默认的可用代码片段,但是您始终可以为自己经常使用的代码模式创建自己的自定义代码片段,并将其保存在代码片段库中。 由于我们不必重复/重写代码,因此节省了大量时间,并且还有助于避免代码中的错误。 使用可用的代码片段 要查看可用的代码段,请转到编辑器右侧的“实用程序”面板。 然后,在“实用工具”面板的下半部分,将有一个带有4个图标的水平分隔线。 可从对象库旁边的第二个选项卡访问Xcode代码段库,在这里我们可以抓取所有UI组件以将它们拖到Storyboard上。 单击{}图标以显示代码段库。 在这里,您可以找到一些预定义的代码片段。 有两种方法可以使用这些代码片段或将其插入代码中。 您只需在需要的地方将其拖放到源代码中即可使用它们。 您开始输入一些代码,然后代码完成提示会提示您 这是Xcode内置的一些可用片段的列表: 枚举,结构联合和块的Typedef声明 控制流程语句,例如if,if…else和switch 循环,例如for,while和do…while 内联块变量声明 @interface(包括类扩展名和类别),@ implementation,@ protocol的Objective-C声明 Swift函数语句,Guard语句,枚举类型声明 初始化,initWithCoder:和initWithFrame:方法实现或快速的Initializer / Deinitializer声明的Objective-C咒语 Swift Do-Catch语句或Objective-C try-catch-finally块 如何添加自定义代码段? 在Xcode中,您可以添加自己的代码段。 要添加自定义代码段,请按照以下简单步骤操作: 在代码编辑器中写下您的代码。 现在,在Xcode的右下角打开代码段库视图。 选择您的代码段,然后将其拖到代码段库中即可。 它将提示一个窗口,用于添加标题,快捷方式,语言和摘要。 在标题中,输入将用于标识代码段的代码段的名称。 总之,您可以给出简短说明,以指定此代码段的功能。 输入您的代码段的快捷方式。 如果在代码编辑器中键入快捷方式文本,则会弹出自动完成代码。 通过使用这个你可以 选择平台和代码段应使用的相应语言。 完成范围对于确定代码片段应在哪些范围(方法,类实现,初始化器等)中也很方便。 您还可以编辑刚刚保存的代码段,并添加代码占位符。 要创建占位符,只需输入 在处理仅需要将不同变量传递到其中的某些代码时,它确实很有用。 编辑自定义代码段 添加新代码段后,我们也可以选择对其进行编辑。 双击代码片段,将出现一个弹出窗口。 在此弹出窗口中,左下角有一个编辑按钮,通过选择编辑按钮,您可以在库中编辑代码段。 瞧! 现在,您已经创建了一个新代码段,它将使Xcode在您下次使用时自动为您完成代码。 […]

了解Xcode游乐场

运动场是一种交互式环境,可以在其中输入和执行Swift代码,并实时显示结果。 这是学习Swift语法和iOS应用开发可视化方面的理想环境,而无需在通常伴随标准Xcode iOS项目的编辑/编译/运行/调试周期中连续工作。 我可以使用游乐场创建UI吗? 答案是肯定的。 Playground使您能够像在项目中一样设计UI。 您所需要做的就是将XCPlayground导入到您的游乐场。 而已! XCPlayground是一个框架,它扩展了UIViewController和UIView以采用XCPlaygroundLiveViewable协议。 该协议允许UIViews和UIViewControllers显示为游乐场页面的实时视图。 如果就是这样,让我们​​开始四处张望。 首先,我将通过在“ Sources”目录内的Swift文件中创建一个View Controller来构建表视图。 该目录中的所有文件都被编译到一个模块中,并自动导入到Playground中。 通过在具有public可访问性的那些文件中定义任何类型,函数或全局常量,我可以在Playground中使用它。 此外,与在创建任何项目时一样,将工作组织在单独的文件中也是一个好习惯。 如果不使用Playgrounds,则每次您要检查动画的组合方式时,都必须重新构建项目。 项目越大,花费的时间越长。 使用Playgrounds,您可以快速创建和优化动画,并获得正确的视觉反馈。 让我们进行一下拍摄,然后尝试通过创建一个包含两个图像视图的大视图来对昼/夜圆进行动画处理,其中一个视图用于太阳,另一个视图用于月球。 您可以将图像添加到“资源”文件夹中的操场上,在其中可以保留相关资源,例如图像,数据文件等。 基本上,在创建了这三个视图(赋予它们大小和添加约束)之后,我们将创建两个功能,一个功能为视图的背景色设置动画,另一个功能为太阳和月亮的运动设置动画。 同样,不要忘记使实时视图等于主视图(包含所有视图的视图)。

使用loadView()编写更清晰的Swift View代码

最初发布于 swiftrocks.com 。 在使用情节提要和以编程方式编写视图之间的选择非常隐晦。 过去已经处理过这两个问题,我个人保证完全通过视图代码编写项目,因为它允许多个人在同一个类中工作,而不会造成棘手的冲突,并且代码审查更加轻松。 从以编程方式编写视图的实践开始,人们面临的一个普遍问题就是将代码放在首位。 如果您遵循将所有与视图相关的内容放入视图控制器的常规情节提要板方法,那么最终获得一个巨大的神类非常容易: final class MyViewController: UIViewController { private let myButton: UIButton = { // }() private let myView: UIView = { // }() //Other 10 views or so override func viewDidLoad() { super.viewDidLoad() setupViews() } private func setupViews() { setupMyButton() setupMyView() //setup for all the other views } private func […]

重用情节提要视图(非编程方法)

当涉及到重用视图时,许多建议涉及创建XIB文件,扩展UIView类以及覆盖多个初始化程序以通过编程方式加载NIB资源。 有一个更简单的替代方法,它仅处理情节提要,并且不需要任何编码。 首先,将Container视图从对象库中拖放到父视图中。 该容器带有一个空白视图,该视图将用作设计可重复使用组件的工具。 为了将我们的可重用视图包含在其他容器中,我们希望将其重构到自己的情节提要文件中。 幸运的是,在“ 编辑器”菜单中只有一个命令(称为“ 对情节提要进行重构” )。 严格来说,只有当我们在不同的故事板上有多个父母时,这才是必需的,但是我认为无论如何它都可以增加清晰度。 一旦进入独立的情节提要板,我们就可以继续处理我们的视图。 需要注意的一件事是视图如何保留其自己的控制器,而不必受特定设备长宽比的约束。 自动布局约束会像往常一样强制执行,这对于使用NIB方法的传统负载而言并不容易 。 要将视图嵌入其他容器中,我们再次将容器视图对象与库窗格中的情节提要引用结合在一起。 这次,请确保立即删除蝙蝠容器视图附带的空子视图并进行检查。 然后,将控件从容器拖动到情节提要参考上,并选择在viewDidLoad下的Embed以重新创建特殊的脚本。 最后,不要忘记在检查器上配置情节提要参考以指向我们可重用组件的文件。 就是这样,现在组件将在我们告诉它的所有位置进行渲染,并在容器范围内进行适当的布局。

克服你的[弱者]

我知道。 今天是星期三。 我通常在星期五发布。 但是金莺正在崩溃和燃烧,所以我的夜晚突然变得不那么忙了。 几周前,我写了关于自动引用计数和强引用周期与弱引用周期的文章。 仔细研究这个问题确实使我在脑海中强化了这个话题。 我真正在努力的是: var someFunction:()->字符串= {[弱自我] 返回“嗨!我是帕特!” } …这他妈到底是什么? [弱者]? 我很害怕。 好吧,当我第一次学习它时,有一些信息让我感到惊讶:闭包是引用类型。 是的 谁知道? 你可能知道。 我没! 我一直在假设闭包是值类型,因为,就像您知道的那样。 迅速。 Swift❤值类型。 但是不。 Swift闭包确实是引用类型。 下面的示例我来自开发人员Bob,因为它很好地说明了将闭包作为引用类型。 如果我们有一个闭包数组,然后将闭包附加到该数组: var闭合数组:[()->()] = [] 变量i = 0 _ in 1 … 5 { closureArray.append {print(i)} 我+ = 1 } 您可能希望当我们在closureArray中调用每个单独的闭包时,它会打印出1到5的数字。但是,事实并非如此。 而是,每个闭合将打印出数字5。为什么!? 因为傻瓜,我们正在使用引用类型。 我们所有的五个闭包都引用内存中的同一点。 当我们为这些闭包之一更改“ i”的值时,我们为所有这些闭包更改了它。 当实例化每个闭包时,我们不会在闭包中为石头设置“ i”的值。 我们只是告诉闭包每次调用闭包时都引用i。 幸运的是,Swift向导的神奇顺序使我们可以解决。 […]

学习Swift和iOS开发:一系列。 – devslopes

学习Swift和iOS开发:一系列。 欢迎来到编程和iOS开发的世界。 欢迎来到充满创造力,激情和想象力的神奇世界。 在这里,我们将代码转化为可以使人们愉悦,娱乐和改变人们生活的体验。 首先先说一点。 学习编码可能很困难。 这也是我做过的最有意义的事情之一 。 我自学了30岁的代码,所以无论您是大人还是小孩子,您都可以学习编码。 您有时会灰心。 您将告诉自己:“我对此没有头脑”,您将要放弃。 您可能会遇到欺负网络编码人员的恶棍,这些人贬低了您的编码技能,并告诉您,除非拥有计算机科学学位,否则您不是真正的程序员。 但是然后事情就会开始点击。 您将编写一些代码,并且该代码将起作用,并且您自己会想到:“伙计,我很棒。” 我想给您一些建议,以使您在遇到挫折时保持直截了当: 1.不要将自己与其他程序员相比。 与自己竞争。 有人永远比你更熟练。 2.您确实属于编程世界。 不管别人怎么说。 作为程序员,您拥有独特的才能,而其他程序员则没有。 3.如果学习很痛苦并且大脑受伤了,那就知道自己正在成长。 程序员可以过着有意义的生活。 我的编程生涯是在家中度过的。 这意味着与我的家人在一起,这是我的首要任务。 成为一名优秀的程序员,您将有机会过上任何想要的生活方式。 这是一种拥有更多个人时间和自由的生活方式,还是那意味着为顶尖公司工作而赚到丰厚的薪水-或者也许两者都有! 在您学习编码的过程中,我能告诉您的最后一件也是最重要的事情是—每天学习,每天做一些动手编码。 您的知识将会复合,您的进步将成倍增长。 那么,我们将在本系列中介绍什么? 很多。 以下是即将发生的事情: 了解Swift的基础知识。 涵盖变量,函数,数组,循环,字典以及所有这些好东西。 我们将介绍UIStackViews并构建您的第一个iOS应用。 了解有关地图,自动版式和手势识别器的信息。 了解应用程序设计,Sketch基础知识以及UX和UI到底是什么? 我们将学习如何与API交互,使用Firebase以及一些单元测试。 还有更多。 因此,如果您准备好开始,那么我们就开始阅读有关安装Xcode的第一篇文章。 准备。 组。 走。

NSFetchedResultsController不想被模拟

更具体地说,NSFetchedResultsController的Objective-C泛型不能很好地与Swift协议的relatedtype配合使用。 “测试工程”背后的思想是,不是针对具体类的接口编写代码,而是针对具有相同接口且具体类遵循的协议编写代码。 对于“真实”构建,使用真实对象。 为了进行测试,可以替换模拟对象或伪造对象,从而进行可靠的测试。 对于基于Core-Data的应用程序,这意味着创建一个我们要针对其进行编码的“ NSFetchedResultsControllerPrototol”。 NSFetchedResultsController实际上有一个使用的泛型类-它的原始定义为NSFetchedResultsController : NSObject where ResultType: NSFetchedRequestResult 。 这对我们来说是完美的,因为这样我们可以使用关联的类型,然后用模拟代替所出售的对象。 在写出该方法时,不会产生任何内联错误,并且在进行规划和开发的前提下,这是可行的。 但是,到了构建的时候,结果却截然不同: 编译期间的分段错误意味着编译器本身已崩溃。 不幸的是,使用泛型时经常发生这种情况,短期内别无选择,只能解决。 (但是在此之前,警告是一团糟,错误看上去像表情符号,说明它们如何使您感觉:’_’,等)。 iOS的核心功能仍然是本机Objective-C,即使以Swift表示,也要等到验证尽可能接近您的特定用例后,才能假设它会起作用。 仍然可以模拟核心数据,包括健壮的模拟; 随后的文章将对其进行探讨。 编辑:现在归档为 Open Radar 35110402 。

Swift 1中的核心数据:创建纯Swift NSFetchedResultsControllerDelegate

在Swift中使用Core Data的路径不像高速公路,而更像是一条依山傍水的危险小径。 但是,像许多Swift问题一样,问题不是新的危险,而是现有的不安全做法正在被揭示。 一种方法是简单地重新创建不安全的做法,例如使用隐式展开的可选方法。 另一种方法是将所有内容包装在“ guard”和“ if let”的多个级别中,以使控制流隐藏在不必要的分支中。 无论如何,Objective-C的假设在框架中构建得越深,在与众不同的Swift世界中就越难使用。 即使系统已试图弥合差距,例如将具有混合结果的Objective-C泛型添加到NSFetchedResultsController中,这也是正确的。 编译器崩溃后,需要另一种方法。 与许多Cocoa委托一样,在Swift中使用NSFetchedResultsController的可能性受到它所施加的要求的限制:委托必须是NSObject,其方法必须是Objective-C,并且回调不能是通用的。 目标是使NSFetchedResultsControllerDelegate适应隐藏其旧的Objective-C包。 这可以通过将NSFetchedResultsController包装在一个适配器类中来完成,该适配器类确实满足旧的要求,并在纯Swift中传递新的委托回调。 第一步是将委托重新创建为Swift协议: 这里的接口几乎与NSFetchedResultsControllerDelegate完全匹配(省去了无关的controller(_:sectionIndexTitleForSectionName) )。 该关联类型被命名为ResultType,并且由于它将是NSFetchedResultsController的ResultType,因此具有NSFetchRequestResult约束,但是我们并没有通过要求编译器将Objective-C桥接到Swift泛型而混淆了编译器。 注意,我们仍然使用NSFetchedResultsController:我们还没有准备好重构它。 现在的目标是适应代表。 因此,我们保留NSFetchedResultsController及其相关的“ NSFetchedRequestResult”和“ NSFetchedResultsChangeType”。 然后可以构建适配器: 即使不对泛型进行解码,也很难避免发生的事情:来自NSFetchedResultsController的委托消息被转换并传递给FetchedResultsControllerDelegate实例。 每个细节都需要考虑,但是要逐行考虑: 类声明和属性 像大多数泛型一样,类的声明可能不是直觉的。 大致可以分为三个部分: 1) class FetchedResultsControllerAdapter FetchedResultsControllerAdapter具有单个通用类型Delegate,它是我们之前创建的FetchedResultsControllerAdapterDelegate的实例。 AdapterDelegate在类型上必须是通用的,因为正如大多数Swift开发人员所了解的那样,由于它具有Self或关联的类型要求,因此只能用作通用约束。 在整个课程中,我们将其称为“委托”。 由于Delegate具有ResultType,因此我们也可以引用它,例如在Fetched Results Controller属性中: private(set) var fetchedRequestController : NSFetchedResultsController 这是确保NSFetchedResultsController和Delegate的ResultType匹配所必需的。 2) NSObject, NSFetchedResultsControllerDelegate FetchedResultsControllerAdapter是一个NSObject,它符合NSFetchedResultsControllerDelegate的要求。 3) where Delegate: AnyObject 对于内存管理存在此约束。 代表是保留周期的经典来源。 如果此对象强烈引用其委托,使其保持活动状态,并且如果该委托强烈引用该适配器(几乎可以肯定),则使其保持活动状态,则将永远不会释放这两个对象。 […]

iOS Swift新手Gotcha提醒#6-减速带及如何优化XCode 10以加快构建时间!

注意1:编译模式:用于调试的应始终为 Incremental 而释放应为 Whole Module 注意2:优化级别:默认情况下,启动新项目时应正确设置。 您可以通过以下链接阅读有关快速优化的更多信息: Swift 3中的整体模块优化 全模块优化是Swift编译器的优化模式。 整个模块的性能胜利… swift.org 另外,如果您使用cocoapods,则可能可以编辑吊舱的post post安装方法以启用正确的选项,而不必费心处理每个设置。 post_install做|安装程序| installer.pods_project.targets.each做| target | target.build_configurations.each | config | 如果config.name ==’调试’ config.build_settings [‘OTHER_SWIFT_FLAGS’] = [‘$(继承)’,’-Onone’] config.build_settings [‘SWIFT_OPTIMIZATION_LEVEL’] =’-Owholemodule’ 结束 结束 结束 结束 步骤3.减少并发作业数,并为合适的作业获得合适的硬件。 收益递减法则在这里起作用。 您将看到具有更多并发作业以匹配cpu的数量将大大降低构建时间。 建议您在计算机中使用四个以上的内核,以将其减少到5个并发作业。 通过终端命令行输入以下命令,以使用以下命令设置Xcode允许的最大并发作业数。 默认写com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks 5 步骤4.确保XCode10中的“ parallelize build”设置 转到您的方案: 编辑方案>构建>构建选项,并确保并行化构建已打开。 在XCode9中,资源以线性方式构建,这花费了更多时间。 但是,在XCode10中,我们可以利用并行化构建设置来通过所有并行资源大大缩短构建时间。 参考文献: fastred / Optimize-Swift-Build-Times 收集有关优化Swift项目的编译时间的建议。 […]