Tag: 编程

为什么我比Interface Builder更喜欢代码

本文 最初发布在我的博客上 。 像今天许多iOS(和macOS)开发人员一样,我通过遵循Apple自己的教程开始为Apple设备进行开发。 我仍然记得,在2011年并且来自Python和C ++的背景下,在助手编辑器上打开.xib文件和相应的类,然后从一个文件拖到另一个文件以创建IBOutlets和IBActions ,是多么神奇。 我想,“太好了”。 摆脱样板代码而只关注我的应用程序应该做的事情确实令人耳目一新。 没多久,我开始看到依靠这种矛盾的缺点。 特别是当我从从事小型教育项目转为开始与其他开发人员进行大型项目时。 合并地狱 .xib和情节提要板都不是人类可读的。 您应该使用Xcode为您生成的那些文件的漂亮图形表示。 这意味着,如果您和您的同事碰巧在同一个文件上进行工作,那么其中一个将不得不在以后解决合并冲突。 很多时候,合并将涉及随机选择更改,然后在Xcode上打开文件并弄清楚需要做什么以确保文件处于所需状态。 最后但并非最不重要的一点:Xcode只需打开它们即可更改Interface Builder文件。 有时,稍加修改就会导致文件的大量更改(这是因为文件的XML节点在内存中表示为一个集合 ,而集合不能保证顺序)。 其他时候,Xcode只是为了好玩而更改.xib的语法。 紧密耦合,几乎没有编译时间安全 您是否曾经运行过您的应用程序,并确信它会按预期运行,只是在您打开某个视图控制器后看到它崩溃了? 在检查了崩溃的确切原因之后,发现这是未连接的IBOutlet吗? 是的,我们都去过那里。 此外,Interface Builder文件更难重用,甚至更难重构。 几乎不可能单看这样的文件并对文件定义的所有内容都一清二楚。 当涉及到Interface Builder的问题时,我几乎看到了所有事情。 从可能突然使Xcode崩溃的文件仅从打开某个文件到可以使用不同xib实例化的视图控制器开始,并且当使用这些xib中的一个实例化实例时,可能导致崩溃,因为等待它,因为IBOutlet没有该xib上的对应元素,并且由于Xcode生成IBOutlets作为隐式解包的可选变量,因此任何尝试访问该变量的尝试都会导致应用崩溃。 拖拉东西不是我的强项 有一些小事情使通过“界面生成器”添加约束的任务变得异常艰巨。 就像必须移动到下一个布局约束字段一样,以便当我单击“ 添加约束” ,Xcode打开单个Storyboard所花费的时间,或者正在编辑某些内容并使Xcode崩溃时,Xcode不会忽略我的约束。 (然后必须重新打开该项目,并找出最后保存的更改是什么)。 当用代码完成UI工作时,更容易准确地查明发生了什么或需要更改一年前编写的代码中要实现该新功能的内容。 特别是,如果代码是出于良好实践的考虑而编写的,那么所有内容都是明确的,我将确切地知道在哪里查找。 这使我想起了我使用Python多年的乐趣:显式比隐式好。 但是编写自动布局代码是如此冗长而乏味…… 有一些框架可以消除编写自动布局代码的痛苦。 我选择的框架是制图学。 制图使编写自动布局代码极其简单和直观。 只需从项目的自述文件中查看以下示例: constrain(view) { view in view.width == 100 view.height == 100 […]

戴夫·托马斯(Dave Thomas)的数据处理卡塔(Kata)的快速解决方案(3)

戴夫·托马斯(Dave Thomas)的数据处理卡塔(Kata)的快速解决方案(3) 保持干燥 在第3部分中,要求我们从第1部分和第2部分中干燥(不要重复自己)代码。我的完整解决方案可以在这里找到。 拿起先前编写的两个程序,并尽可能多地分解出通用代码,剩下两个较小的程序和某种共享功能。 第1部分和第2部分中的分配非常相似。 每一项都要求我们加载文件,将文件的文本提取到表中,清理每一行,选择我们感兴趣的列,然后查找并打印两列之间的差异最小的行名。 我将Dave的说明解释为“留给您两个小程序”,意味着我应该创建我的“ Executor”结构的两个版本,一个用于天气,另一个用于足球数据。 在一个实际的项目中,我将合并为一个结构,该结构接受闭包作为两种数据类型之间不同的每种方法的参数。 考虑到我略微潮湿的“法律法规”方法,有两种方法需要重构。 removeUnneededColumns() 由于每个文件都有我们需要使用的不同列,因此不再可以对其进行硬编码。 我的方法是包括一个validColumnIndexes:[Int]参数。 然后,我们遍历每个索引并返回该行中单元格的映射。 静态函数removeUnneededColumns(fromTable表:[[String]],validColumnIndexes:[Int])-> [[String]] { 返回table.map {(行:[String])在 返回takeNeededColumns(行:行,有效列索引:有效列索引) } } 私有静态函数takeNeededColumns(行:[String],validColumnIndexes:[Int])-> [String] { 返回validColumnIndexes.map {row [$ 0]} } 。评估() 我们的评估方法也需要更改,因为在接受特定类型的数组之前。 为了解决这个问题,我创建了WeatherRecord和FootballResult都符合的DifferenceCalculatable协议。 协议差异可计算{ var名称:字符串{get} var差异:Double {get} } 这样一来,我们就可以创建一个通用的评估方法,该方法的类型必须限制在DifferenceCalculatable中,从而可以访问.difference和.name, 静态函数评价(项:[元素])->字符串? { 令lettDelta = items.minElement {$ 0.difference <$ 1.difference} 警卫队让名字= minimumDelta?.name其他{返回nil} 返回“ \(名称)” } 符合DifferenceCalculatable意味着我必须将WeatherRecord的let […]

创建自己的CocoaPod库

CocoaPods是本机iOS / macOS项目的依赖项管理器。 它具有成千上万个库,可以通过共享而不是共享项目的整个库集,而仅共享包含有关依赖项的所有信息的单个Pod文件,来帮助您优雅地扩展项目。 最终,其目标是通过创建一个更加集中的生态系统来提高第三方开源库的可发现性和参与度。 不仅如此,您还可以在私有存储库中创建pod,因此没有人可以访问它,并且您将获得CocoaPods的所有好处。 首先,让我们看一下cocoapods到底是什么 : 在这里,您可以看到cocoapods将所有依赖项存储在其他位置(例如GitHub上的代码,gitlab等),以及关于cocoapods仓库的pod信息。 因此,对于创建Pod,您应该将代码存储在某个仓库(公共或私有,您可以选择)上,并将Pod信息提供给cocoapods。 Pod信息实际上是一个.podspec文件,其中包含有关库的所有信息(请参见下文)。 因此,podspec基本上如下所示: Pod :: Spec.new do | s | s.name =’MyLibrary’ s.version =’0.1.0′ s.summary =’真棒’ s.description = <<-DESC 帮助您飞行。 数据中心 s.homepage =’http://example.com’ s.screenshots =’www.example.com/screenshots_1′ s.license = {:type =>’MIT’,:file =>’LICENSE’} s.author = {‘Maxud’=>’nuves101@gmail.com’} s.source = {:git =>’http://github.com’,:tag => s.version.to_s} s.social_media_url =’https://twitter.com/ ‘ s.ios.deployment_target =’7.0′ s.platform =:ios,’7.0’ […]

[Code :: Blocks]使用MinGW-w64在Windows下编译64位

使用Code :: Block的最大好处之一是,在编译器之间进行切换非常容易。 在此博客中,它显示了如何将MinGW-w64(适用于Windows的GNU)添加到代码博客中,并使用它来编译64位程序。 1.安装MINGW64 下载并安装MinGW-w64。 假设您将其安装在C:\ mingw64下 。 2.设置编译器 打开代码::块 。 转到设置>编译器 。 在所选编译器的下拉列表中,默认情况下应选择GNU GCC编译器 。 我们将复制此编译器的设置,然后对其进行修改。 单击复制,然后为要设置的编译器提供一个新名称。 您可以随意命名(例如GNU GCC编译器(x64) )。 最后一步,您需要更新工具链可执行文件标签下的工具链 。 将编译器的安装目录修改为MinGW64的目录(例如C:\ mingw64 )。 同时在“ 程序文件”下更新以下内容: C编译器: x86_64-w64-mingw32-gcc.exe C ++编译器: x86_64-w64-mingw32-g ++。exe 动态库的链接器: x86_64-w64-mingw32-g ++。exe 静态库链接器: x86_64-w64-mingw32-gcc-ar.exe 现在,您可以继续使用此编译器来编译程序。 3.设置调试器 通过上述步骤,您将无法调试程序。 您可能会收到以下错误消息: 启动调试对象失败:未指定可执行文件,请使用“ target exec”。 调试器状态为0 现在,您必须在设置>调试器…下设置调试器 。 在GDB / CDB debgger上选择,然后创建Config 。 […]

迅捷金属乐

适用于iOS和macOS的超快速着色器和管线探索 在过去的几年中,与许多开发人员一样,在Swift Playgrounds中工作时,我对编辑/编译/运行周期的速度不满意。 Swift Playgrounds让我们有机会轻松编写快速代码以测试概念,而无需构建完整的应用程序,部署到设备或模拟器以及观察结果。 我已使用Swift Playgrounds更好地了解了许多技术,包括: 斯威夫特语言概念 核心动画 SpriteKit 场景套件 一个让我难以理解的领域是在Swift Playground的Metal中工作。 Metal是Apple的底层图形系统,旨在利用自己的硬件并提供出色的性能。 我相当怀疑是否有直接在Metal中工作的实际输出-SceneKit对我来说做得很好-但我仍然感到需要挠痒痒。 因此,另一个游乐场冒险开始了。 配置游乐场 在创建用于Metal开发的游乐场时,需要将其设置为macOS游乐场。 iOS操场不符合条件,因为模拟器无法提供我们进行Metal开发所需的直接GPU访问。 我们需要导入一些框架。 为了处理我们的macOS视图,我们需要访问Cocoa。 我们需要Metal才能与Metal合作。 最后,我们需要PlaygroundSupport才能显示Metal视图。

面向协议的编程:一种快速的OOP头痛解决方案

为什么OOP如此受欢迎? 面向对象编程(OOP)是数十年来编写模块化代码的经典策略,并且有充分的理由。 可重用性:编写良好的对象是可以插入其他程序的独立实体。 如果实现了优化的树,则可以在现有项目的任何部分或全新的树中使用它,而无需编写更多代码。 跳过细节 :另一个程序员不需要知道您对象的实现。 如果看到“排序”功能,则可以使用而不必担心代码是什么样。 防错 :我们可以隐藏对类中函数或变量的访问,以防止其他不熟悉我们代码的开发人员创建错误。 其他人只会看到他们需要看的东西。 使大型项目易于管理:大型 项目变得复杂。 OOP使我们可以将一个大问题分解为一些子问题-每个子问题都由不同的对象处理。 如果Nabil,Julia和Alex正在制作太空侵略者游戏。 纳比尔(Nabil)可以建立一个代表外星人的对象,朱莉娅(Julia)可以建立一个GameBoard对象,该对象可以跟踪我的得分,生命数以及游戏开始/结束的时间,而亚历克斯(Alex)可以创建代表我的坦克及其导弹的对象。 最后,我们将这些对象组合在一起,以构建功能强大的游戏。 更新代码:使用模块化代码,随着时间的推移,我们可以轻松编写添加,更新或删除特定组件的代码。 例如,在用砖建造的建筑物中,您可以用新砖替换掉破裂的砖,而不必替换建筑物的整个部分。 与旧同在 虽然非常方便,但是OOP附带了很多问题: Massive View Controller,“ GOD”对象 :为了保持模块化,程序员使用一种类别,一种目的的主体。 但是,view肿的viewController和模型是流行的快速设计模式(MVC,MVVM)的常见副产品。 传递大块的对象会减慢您的代码的速度,并在构建时使模块化变得困难。 如果一个对象拥有您所需的太多功能,那么您编写的新代码也将最终取决于该对象。 多重所有权:假设您和一位工程师(Nick)正在使用引用同一BankAccount对象的单独ViewController。 如果您在firstViewController中添加功劳,而Nick在secondViewController中删除功劳,则两个人最终都会得到意外的结果。 类是通过引用传递的,因此,在项目的一个区域中更改值将导致该对象的值在所有其他位置均发生更改。 这使得很难测试功能对给定对象的隔离效果。 子类问题:如此之大的问题应有其自己的部分

完整的iOS 10设计和开发Bootcamp

完整的iOS 10设计和开发训练营 如果您是iOS开发的初学者 ,那么您的位置很好。 如果您已经尝试学习开发并遇到了beta错误(例如代码无法正常工作)的问题,那么您也很幸运。 我们在本课程中设计的所有应用都是在Xcode 8正式发布之后进行设计和编码的 。 甚至没有一个应用程序会给您带来代码冲突问题。 应用开发是一个过程。 设计应用程序 ,创建用户界面并编写代码以使该界面正常工作的过程。 我们将使用Sketch应用程序设计应用程序的UI,并使用swift 3编写应用程序的后端逻辑。 这次训练营还包括有关Swift 3和Sketch App的完整课程。 在设计整个课程课程时,要牢记学生要花时间学习,每个主题都必须在特殊的时间展示,以便学生轻松学习。 我们将首先为新主题创建一个测试应用程序,然后将创建一个包含针对我们刚刚学到的知识的应用程序的应用程序。 我们将学习约束和堆栈视图,相机,照片库,麦克风等。此外,我们将继续学习Firebase ,并探索诸如身份验证,实时数据库和存储之类的Firebase服务。 我们不仅会创建演示应用,还将学习为该应用创建图标和专业图形。 是的,我们本可以为图形资产提供很多价值,但是相反,我们将在此课程中教您设计这些资产。 学习完本课程后,您将学习阅读文档,并学会自己解决问题。 让我们开始吧。 #ios 10 #xcode 8 #sketchapp #firebase #development #development bootcamp 链接教程:完整的iOS 10设计和开发Bootcamp

Swift的最佳图像下载,处理和缓存库

大家好! 我想介绍一下我最新的下载,处理和缓存管理器库选择。 更新:2017年12月1日。 PINRemoteImage PINRemoteImageManager使用下载和处理任务的概念来确保即使多次调用下载或处理图像,也只会发生一次 安装 使用CocoaPods将PINRemoteImageManager添加到您的项目中。 只需将以下行添加到您的Podfile中即可。 pod’PINRemoteImage’,’〜> 3.0.0-beta’ 然后运行: pod install SDWebImage 该库提供了具有缓存支持的异步图像下载器。 UI元素有类别,例如UIImageView , UIButton , MKAnnotationView 。 安装 使用CocoaPods将SDWebImage添加到您的项目。 只需将以下行添加到您的Podfile中即可。 pod ‘SDWebImage’, ‘~> 4.0’ 莫阿 Moa是使用Swift编写的图像下载库。 通过设置其moa.url属性,它允许下载图像并在图像视图中显示图像。 安装 使用CocoaPods将Moa添加到您的项目中。 只需将以下行添加到您的Podfile中即可。 pod ‘moa’, ‘~> 8.0’ 然后运行: pod install 文森特 一个小型图书馆,可以轻松下载和显示远程图像。 安装 使用CocoaPods将Vincent添加到您的项目中。 只需将以下行添加到您的Podfile中即可。 pod ‘Vincent’, ‘~> 1.5.4’ 然后运行: pod install 翠鸟 Kingfisher是一个轻量级的纯Swift库,用于从Web下载和缓存图像。 […]

开始Swift编程第5部分-函数,枚举和作用域

在上一篇文章中,我们介绍了if语句,while循环和for-in循环(通常仅称为for循环)。 开始进行Swift编程第4部分-决策和循环 在上一篇文章中,我们介绍了运算符,可选值和nil值。 medium.com 其中一些if语句非常大,如果我们想在该if语句中做多个事情怎么办? 它们将变得庞大且难以阅读。 这就是今天的全部。 让我们潜入。 功能 实际上,您可以在Swift中编写任何功能的程序。 我敢肯定,来自其他语言的人们正在思考,哦,是的! 事实是您真的不知道。 我们将在作用域部分中对此进行更多讨论,但是在全局范围内编写的代码将用作程序的入口点 。 入口点只是一种说法,这是程序启动时首先运行的代码。 很容易,对吧? 我们编写函数是因为它破坏了我们的代码,使其更易于阅读。 我们可以遵循一些编程原则,这些原则实际上只是为了使您的工作更轻松的准则,虽然列表并不详尽,但是足以让您思考如何使代码变得更好: 关注点分离 —如果您对字符串中的字母进行计数然后将两个数字相加,则可以采用这两个单独的函数,一个函数对字符串中的字母进行计数,另一个函数对数字进行累加。 单一责任原则 -概括为以下短语:每件事都有一份工作,每件事都做得很好。 不要重复自己(DRY) -这很明显,为什么要多次输入相同的文本? 为什么要多次输入相同的文本? 这让您发疯,知道我曾经做过,如果您是A型性格,但是当A型开发人员看到一遍又一遍写相同的东西时,他们就会发疯,这是个坏消息,几乎每个阅读您的代码的开发人员都在使用当他们这样做时,请输入心态。 你明白了吗? 好! 我们将在以后再讲更多,但是现在,这是一个很好的基础。 让我们开始向您展示一个用Swift编写的函数的示例。 语法可能看起来很奇怪,但我们将介绍所有内容。 我知道这乍看起来可能会令人困惑,但让我们来看一下。 首先,我们使用func关键字定义一个函数。 这让编译器知道,嘿,我希望下一个代码块可重复使用。 接下来,我们给函数命名为addTwoNumbers 。 函数名称后带有括号,如果没有参数,则将其保留为空: func doStuff() { /* doing stuff */ } 如果有参数(可以传递给函数的东西),则将它们包括在声明中。 在上面的示例中,我们确实有参数,确切地说是两个,我们有number和otherNumber 。 这些在示例中不是很具描述性,但应该是 。 您可能会注意到,我使用了number firstNumber和otherNumber secondNumber 。 number和otherNumber是我们在以后的调用中将引用这些参数的内容,因此我们知道我们要为哪个参数设置值。 […]

iPhone X和WWDC:如何快速成为StackOverflow的iOS专家

如果您想成为一流的iOS开发人员,则需要在Stack Overflow(SO)方面享有很高的声誉。 为什么? 它教你如何提出很好的问题 它会使广告掉下来,这也许是您每天都会使用的最重要的网站 它使您可以发表评论和投票,从而充分利用SO 确保您知道如何像冠军一样使用SO 它使您与众不同,让人们知道您在乎自己的手艺 通过为难回答的问题设置赏金,您可以直接为团队做出贡献 但是要达到2000 rep的堆栈溢出并不像以前那么容易。 大多数简单的问题都得到了回答,这是一条口号,您发布的每个答案只能获得10分。 那是(且仅当)您被投票或被接受为答案时。 假设有50%的时间您的答案获得积分,那就是您必须发布400个答案才能获得2k的收入! 那么,iOS开发人员该做什么呢? 好吧,我曾经有一个非常简单的策略,就是通过回答Swift问题来获得2k代表。 而对于刚刚发布的iPhone X,则是一年中最佳实践的最佳时机。 基本上,每当发布新的WWDC视频时,您都将有机会充分利用这一策略。 我将其分为4个步骤。 1)选择一个新的Apple API并成为其中的专家 每年六月(有时是九月😆),Apple都会推出一种新的SDK,没人知道如何使用。 因此,如果您观看真正感兴趣的API上的WWDC视频,然后开始试用该技术,您就会知道该API优于90%的开发人员。 发生这种情况是因为大多数人没有时间去尝试苹果推出的所有新技术。 我是用UIStackViews完成的。 我认为这项技术对iOS开发人员来说是天赐的礼物,因为它为iOS提供了一种全新的方式来处理自动布局。 幸运的是,大多数人无法开始使用该技术,因为只有运行iOS 9及更高版本的设备才支持该技术。 因此,我在WWDC上的“堆栈视图”上观看了视频,并用它构建了一些应用程序,然后通过在RayWenderlich.com上观看了教程视频对它们进行了补充。 有了这一新知识,我继续进行步骤2。 2)提取API标签,并回答发布的每个问题 在SO主页上,导航至标记,然后输入您已掌握的新API的名称。 将鼠标悬停在标签上,您就可以通过单击星标来收藏标签,并通过电子邮件或RSS进行订阅。 然后在下个月的每一天,早上检查SO,然后回答所有已发布的问题。 或简单地回答它们,就像电子邮件中显示的那样。 3)格式化答案以发挥最大效用 该策略最重要的部分是答案的格式。 确保执行以下操作: 1)确保您回答的是确切问题 许多人仅仅因为不专注于回答所提出的问题而无法对SO进行投票。 2)尽可能附上屏幕截图或示例代码,以使答案更清晰 我们是视觉生物。 你们是否都尝试过实施仅以文本形式说明的一段代码? 真痛苦! 因此,通过包括屏幕截图和代码,可以简化原始海报(OP)的生活。 3)通过解释答案背后的原因,使答案详尽无遗 堆栈溢出是一个学习的好地方,但是几乎没人教。 考虑周到的答案包括为什么(不仅是如何)获得最多的选票。 当您输入原因时,提出问题的人可能不必再次查找该问题,因为他们将学到的不仅是如何复制和粘贴代码。 刚开始时,您的答案可能不会获得太多投票,但这是计划的一部分,这是一个漫长的过程。 在这一年中,人们将开始使用您已成为专家的API。随着越来越多的人使用它,更多的人将查找您的答案并单击“投票”。 这是我关于Stack Overflow的一篇详尽文章的示例。 现在,如果您知道有人要提出但尚未回答的问题,请使用步骤4。 […]