这是与了解您的计算机及其软件相关的一系列博客文章中的第一篇博客文章。 目的是进一步了解Swift的内部,性能和性能。 我们将介绍计算机(数学)的基础知识,以及结构,数组和快速优化。 这篇文章将介绍位,字节,整数和数学。 位 在计算中,一切都是二进制的。 迅速地, 0b前缀表示字节文字的开始。 然后,所有数字( 0或1 )将字节中的位表示为小端。 0b00000000 该字节为0 ,因为所有位均为0。 字节序 这些位按从大到小(小端)或从小到大(大端)的顺序排列。 Endian,即列表中的最后一位,即列表中最小或最大的数字。 0b10100000 小尾数中的以下数字是128 + 0 + 32 + 0 + 0 + 0 + 0 + 0 ,因此为150 但是,在big endian中,这是1 + 0 + 4 + 0 + 0 + 0 + 0 + 0 ,因此是5 。 最低位代表1 ,每步乘以2 。 […]
Gameboy是(现在仍然是)非常出色的设备。 不仅从游戏玩家的角度,而且从程序员的角度,程序员都希望了解更多有关计算机如何在更基础的水平上工作的信息。 汇编语言,CPU操作码,内存映射的I / O,所有这些都是计算机工作的基础,但是由于我们要进行更高级别的抽象,因此在日常工作中我们并没有真正使用太多东西现在。 但是了解我们日常设备在幕后的工作方式既有趣又有用。 结合起来,复古计算和游戏总是很有趣! 就像我说的,Gameboy就是一个完美的装置。 它于1989年发布,具有基于Z80的8位CPU(与您可能知道的Intel 8080不太相似),具有16位地址空间和1 MHz的时钟速度,以及大约16kb的RAM 。 可执行文件随盒带提供,盒带的大小从32kb到数兆字节不等。 墨盒本身只是一块硬件,因此它还可以具有额外的RAM,电池供电的RAM以保存游戏,甚至还可以提供更疯狂的物品(例如相机)。 而且很容易找到用于运行和调试程序的仿真器。 在本文中,我们将编写一个简单的Gameboy游戏,该游戏仅在屏幕上显示一个精灵。 那不是什么大游戏,但是要达到这一点还需要学习很多东西。 我们将使用我在Swift中编写的汇编程序,您可以在Github上找到适用于macOS和Linux的汇编程序。 本文将首先说明Gameboy CPU的工作方式,然后介绍如何编写汇编程序,然后在Gameboy上图形如何工作,最后,我们将把所有这些部分组合成一个工作程序。 让我们开始学习一下Gameboy的工作原理! CPU和地址空间 理解Gameboy以及实际上任何计算系统的工作原理,主要有两部分:CPU,它接收指令并执行它们,以及地址空间,该地址空间用于访问不同的硬件组件。 当一条指令在CPU上运行时,它会以某种方式修改系统的状态。 通过内存地址访问的CPU内部状态或某些硬件组件的状态。 Gameboy具有16位地址空间,这意味着您可以访问0到65535(十六进制的$ ffff)的内存地址。 Gameboy的硬件已将这些地址中的每一个都映射到某种硬件。 它可能是盒式ROM,声音芯片或某些通用RAM。 编译汇编代码时,它将转换为二进制文件,即一系列操作码。 操作码是一个数字,表示CPU可以执行的一条指令。 例如,操作码$ 00表示NOP,这是一个空操作。 $ 82是一条ADD指令,它将两个数字加在一起。 您的二进制文件是这些操作码的一长串列表,它们位于盒带的ROM中。 盒式ROM存储器映射到Gameboy存储器空间的前半部分,这意味着从$ 0000到$ 7fff的所有地址(这些值更容易用十六进制数字表示。16位值为4密码十六进制数字)。 这意味着,如果您读取介于$ 0000和$ 7fff之间的任何地址,它将从盒带中读取一个字节。 请注意,地址空间是16位的,这意味着到内存位置的每个地址都在$ 0000和$ ffff之间,但是存储在这些位置中的值是8位,因此在$ 00和$ ff之间。 Gameboy CPU将其状态保存在内部寄存器中。 每个寄存器都是一个8位或16位值,直接存储在CPU内部,因此读写非常快,因为它不必通过地址总线与任何其他硬件组件通信。 Gameboy有八个8位寄存器和两个16位寄存器: 8位寄存器:A,F,B,C,D,E,H,L 16位寄存器:SP(堆栈指针),PC(程序计数器) SP寄存器跟踪堆栈的大小(我们将在后面介绍),而PC寄存器跟踪CPU当前在代码中的位置。 就像地址空间一样,这两个寄存器是16位的。 […]
响应式编程是定义响应异步事件的应用程序行为的有用工具。 它将异步操作处理代码从iOS中常见的委托模式转移到更具声明性的形式,使异步性更易于推理。 我没有使用响应式框架从头开始构建应用程序的经验,但是随着我逐渐增加对所涉及概念的理解,我发现在很多情况下,大量的响应式编程已使工作变得更加整洁。更具可读性的代码。 我一直在使用的框架是RxSwift,它是ReactiveX API的Swift实现,但是还有其他可用选项。 在本文中,我们将简要地探讨一个示例,该示例演示如何使用RxSwift创建一个可观察的序列来替换原本会分散在多个不同回调中的代码。 对于我们的示例,要求如下所示,我们必须显示一个垂直滚动的项目列表,每个项目都有一个要显示的图像,该图像必须通过网络异步加载。 我们不能简单地同时从网络中获取所有图像,因为我们的列表可能很长,并且用户甚至可能没有浏览到最后,因此最终可能会因不必要的网络调用而浪费能量和数据。 另一个限制是,当设备连接到wifi时,我们希望浏览的行为不同于连接到蜂窝网络时的行为。 当连接到wifi时,我们希望在用户滚动之前加载图像,以便在屏幕上滚动显示单元时就可以显示图像了。 当连接到蜂窝网络时,我们只希望在用户停止滚动时加载图像,以防止在滚动列表时使用过多的数据。 为了实现此行为,我们需要遵循几种协议,它们是UITableViewDelegate , UITableViewDataSourcePrefetching和UIScrollViewDelegate 。 下面的代码给出了在视图控制器中外观的想法。 考虑到我们需求的复杂性,这并不是一个不好的结果,尽管它确实使我们一眼就很难看出图像加载行为是如何工作的,而且如果这些回调分散在一个大文件中(或几个文件)。 另一个复杂的因素是,这些委托回调通常还需要执行其他功能,这在阅读和理解图像获取行为时会产生更大的背景噪音。 反应式编程如何提供帮助? 我们可以使用反应式编程来定义可观察的事件流,这些事件驱动我们的loadImagesIfNecessary(for:)函数。 每当我们要加载一组图像时,此可观察对象将发出一个由索引路径数组组成的事件。 我们将通过组合和转换与我们感兴趣的委托回调相对应的可观察变量来构造此可观察变量(这些可观察变量在RxSwift的子组件RxCocoa中实现)。 以下是我们如何设置和使用此事件序列的示例。 从功能上讲,这应该与我们最初探讨的传统委托回调实现相同,但是,我认为它使我们的代码更易于理解,因为我们现在可以在一处读取所有图像提取逻辑,而背景噪音却更少。 这是我发现应用简单的反应式编程模式以便组合在一起并简化代码中的复杂逻辑的一种方法。 它确实要求读者对反应式编程原理有基本的了解,并向代码引入了第三方依赖性(反应式编程框架,在此示例中为RxSwift)。 您如何看待这种方法? 以这种方式进行逻辑合并值得额外的开销吗? 如果您有任何建议或问题,请给我@RowbotNZ发消息!
DevMountain培训了很多业余或新手编码人员,这些人员以前很少或没有经验,但是我们也有一些学生已经知道如何编写编码。如果您是一位经验丰富的程序员,那么您可能对回校没有太多的考虑。 我们将解释为什么我们的资深学生会在这里,以及如何学习现代技术技能比您想象的要容易。 1.编码训练营更新您的技能 技术世界飞速发展,如果您不时重新访问自己的技能,那么您可能会落在后面。 DevMountain编码新手训练营使您可以从了解您现在需要了解的现实世界的专业人员那里学习最新的语言和软件。 在我们的网站上查看我们的课程选项,发现从编码新手训练营中学到的新技能! 2.加快了编码训练营的速度/快节奏 作为编码员,程序员或企业家,您不能花时间学习新技能。 DevMountain的新手训练营可让您快速获得所需的培训和信息,并提供全职或兼职学习的选项。 它比回到学校更快,比自学更快。 在DevMountain,我们知道您的时间很宝贵,并且您的日程安排可能很忙,因此无论您的情况如何,我们都会尽一切努力使我们的课程尽可能地易于访问。 3.编码训练营可帮助您建立连接 如果您已经有一段时间了,那么您可能已经知道拥有正确连接的重要性。 我们的新手训练营计划为您提供了与编码专家以及新锐编码员并肩工作的机会。 您还将有机会参加我们的许多活动和会议。 4.给您的简历认真的改头换面 恢复看起来有些乏味吗? 在这里,在DevMountain,我们作为该国评分最高的编码学校之一而享有盛誉,这使其成为任何工作申请中令人印象深刻的补充。 同样,与我们的专家团队紧密合作将确保您离开训练营并获得出色的参考。 5.重新发现您对编码的热情 DevMountain是在您选择的职业道路上寻找新灵感的理想场所。 我们营造一种创造力和发现力的环境,您将被志趣相投的志同道合的人所包围。 这样的专用空间帮助许多学生点燃了对职业的热情。 不过,请不要相信我们的话-在我们的推荐页面上听听我们的学生对我们课程的喜爱。 你还在等什么? 我们拥有您升级简历并将职业提升到新水平所需的一切。 您将能够获得在当今市场上所需的技能,快速获取它们,并在使用过程中建立新的联系。 这是您宝贵的机会,可以充分利用您的时间和教育。 索取课程提纲,以了解您将在DevMountain学习的内容。 您甚至可以与我们的团队见面,并查看他们的证书。 我们迫不及待想要帮助您取得更多成就并继续发展您的事业。
这是什么? 关于仿制药的另一篇文章? 当然可以。 如果我们要确保只能为某些类型调用此函数,该怎么办? 例如,如果我们只想要Int ,而我们稍后将在代码中进行一些数学运算,该怎么办? 在这种情况下, Protocol即将解救。 现在我们重新营业! 我们现在有信心,您未来的自我不会改变任何事情,并确保您的安全和健康。 感谢过去的自我的关注。 因此,我希望您对Generics如何在Swift中工作有更好的了解。 说到扩展,我们实际上可以扩展Sequence并清理firstIn函数。 干净的代码是不错的代码。
首先,让我谈谈property 。 假设如果我们需要使用您的类的对象来更改或访问您的类中的iVar,则应该为该iVar分配getter和setter方法。 主要在其他对象需要更改或访问对象中的ivars时使用属性,而无需手动定义getter和setter或使用@property(在目标– c中)。 在Objective-c中, @property property在类标头中声明一个属性。 这是一个例子: @property (nonatomic, retain) NSString *myString; @synthesize为属性(访问器方法)创建setter和getter。 如果不进行synthesize ,则必须编写自己的setter和getter实现,例如getMyString或setMyString(将属性的第一个字符大写)。 因此,以上属性声明等效于: – (NSString*)myString {} – (void)setMyString:(NSString*)newValue {} 属性可以进一步分为存储属性和计算属性 。 存储属性与计算属性 存储的属性将常量和变量值存储为实例的一部分,而计算的属性将计算(而不是存储)值。 ►计算的属性由 类 , 结构 和 枚举提供 。 ►存储的属性仅由 类 和 结构提供 。 最简单的形式是,存储的属性是作为特定类或结构的实例的一部分存储的常量或变量。 存储属性可以是变量存储属性 (由var关键字引入)或常量存储属性 (由let关键字引入)。 下面的示例定义了一个称为FixedLengthRange的结构,该结构描述了一个整数范围,该整数范围的长度一旦创建便无法更改: struct FixedLengthRange { var firstValue: Int let length: Int } […]
欢迎回到我的Swift开发日记的另一个条目。 如果您关注我以前的记录,您可能已经注意到我不再关注每日报告。 这既是因为不可能一次完成多个任务,而是因为我认为这种内容毫无意义。 然后,我决定切换到“里程碑”模型-也就是说,每当我完成一个项目或取得一些突破时,我都会在这里报告。 如前所述,我正在学习Paul Hudson的Hacking with Swift系列文章,今天,我完成了第一个名为Storm Viewer的项目。 来自带有Swift的App Development课程的非常顺畅和渐进的路径,这令人震惊,因为同时展示了多少功能。 与做事相比,理解似乎排在第二位! 作为古典音乐家,我完全同意! 我在镜子前度过了几个小时,练习打开的琴弦,改变位置等等,而不必了解正在发生的事情。 我的老师曾经说过: «重复并重复一次,直到发现一些东西! » 。 现在我坐在完成的项目前面,感觉是成就的一种,也是困惑的一种。 根据我在最初的几个月的代码学习中了解到的,似乎需要多次遍历该项目的文件,以便一步一步地解决问题。 这当然很合理,但我感到有些迷茫,无法追溯自己的脚步。 因此,我将在此处概述项目建设的进展情况,以便对我进行回顾,并为您提供可能有趣的阅读材料。 通常在这些“简单”项目中会发生这种情况,默认模板是iOS的Single View App 。 解决了Xcode中的初始步骤和Simulator的选择之后,就可以将一些图片导入项目了。 我曾经通过asset.xcassets目录来执行此操作,但是显然这将在以后的课程中进行介绍。 到目前为止,我只是将整个文件夹拖到Xcode项目中,注意选择“如果需要复制项目”复选框,并选择“创建组”而不是“创建文件夹引用” 。 到目前为止,这对我来说还很模糊,但我决定继续。 那里的图像本身几乎没有任何作用,因此是时候了解ViewController.swift文件了。 它包含ViewController类以及其内部的viewDidLoad()和didReceiveMemoryWarning()方法。 在viewDidLoad()内部,我们需要添加一些代码以使应用能够获取图像,使用hasPrefix(:)方法对其进行过滤,然后迭代结果,将其添加到由这些图像名称组成的字符串数组中。 在viewDidLoad()方法中编写一些步骤,然后返回并在其上面编写数组,这有点奇怪,但这似乎是正确的做法。 因此,此设置的第一部分看起来像这样(我已隐藏了以后将添加的部分)。 现在,我们需要使自己熟悉Interface Builder , Auto Layout等。 默认场景被删除,我们代替它绘制了TableViewController 。 当然,仅将其拖动并不会带来很多好处。 需要一些额外的步骤: 告诉Xcode这个新场景将由ViewController.swift文件控制(这是通过将声音更改为Identity Inspector的Class下拉菜单来完成的)。 更改入口优先级(我们希望此View Controller成为应用程序启动时第一个出现)。 在TableView中更改单元格的标识符(以便我们以后可以重新使用它以连接一些代码)+将Style选项更改为Basic。 将整个表视图控制器嵌入到导航控制器中。 默认情况下,TableViewController具有0(零)行,因此我们需要通过实现一些方法( tableView函数的所有子级)来更改该行: numberOfRowsInSection告诉Xcode我们将要显示多少行(该行等于图像数组的.count属性)-区段的数量为1使我们现在跳过该区段。 当我们滚动浏览可能无限数量的行时, […]
在编程中,关于注释的使用一直在进行讨论。 一位出色的Swift博主兼书籍作者Erica Sadun过去写了很多有关评论的文章。 最近,安德鲁·沃纳(Andrew Warner)写了一篇文章,说用代码编写注释通常已过时,甚至对您的代码库有害。 评论衰减。 它们不会被编译,并且永远不会在运行时执行。 如果它们过时或不正确,则不会有测试失败,也不会有用户抱怨。 程序员绕着它们工作是因为担心“有人可能需要此注释,或者它将来可能会提供一些价值”,从而使它们在有用之后就走了很远(如果您甚至可以说它们一开始就有用)。 埃里卡(Erica)对这篇文章做出了很好的回应,强调了注释在代码库中的重要性。 注释不仅仅涉及不良的设计和编码。 他们记录了正确编写代码的过程,支持将来的阅读和修改。 好的评论减少了读者每次查看您的资源时所需的精力,使他们可以将更多的精力放在特定的任务上,例如“我如何添加此功能”,而不是“到底发生了什么”。 我完全同意Erica,并且我想强调一种特殊的方式,其中注释可以帮助您的代码读者。 注释不仅针对错误的代码 过去,我主要与比我聪明得多的高级开发人员一起工作,并且在代码中几乎没有注释。 我们在iOS方面经验丰富,通常不会在同一文件上工作。 因此,我们不会经常遇到代码可读性问题。 但是,在我们最近的项目中,我们招募了新员工,一个精明的Java开发人员仍在学习Swift和iOS。 这是我第一次发现我们的代码有时不可读。 在进行配对编程并看到他遍历我们的代码库时,我可以看到他很难辨别Swift或iOS的组成部分以及什么是我们的代码。 看起来他似乎可以很容易地理解一种方法及其作用,但是很难看到所有部分如何组合在一起。 对于UIViewController中更复杂的代码,尤其如此。 由于UI代码的性质,动画,生命周期方法,样式和表示之类的不同部分都混合在一起并且相互依赖。 在这里,我注意到我们的格言“注释仅针对错误的代码”散开了。 不管代码有多好,阅读代码都很困难。 弄清楚所有这些不同部分如何组合在一起并非易事。 作为开发人员,使阅读代码更容易是我们的工作。 提供背景 在写文章时,我总是特别注意要写的简介。 其目的是为读者建立上下文和动机,以使其了解文章中的查找内容。 如果您阅读的文章没有前几段,那么您将不得不花前几分钟来试图辨别本文的目的。 它是教程吗? 是新闻文章吗? 是广告吗? 在前几段中,您将注意力集中在尝试分析文章本身而不是实际内容上 。 您也没有必要的上下文来理解本文要说的内容。 一篇文章不仅仅是其段落的总和。 这些段落的流动方式和适合的方式建立了共同的线索,并达到了您想要实现的目的。 代码也一样。 一个类不仅仅是其公共方法的总和。 每个类都有责任(一个要点),并与周围的代码(上下文)相适应。 尽我们所能尝试,使用类总是会影响我们编写它们的方式。 没有方法与呼叫站点完全隔离。 每个类都有适合的上下文。 在读取代码时,如果没有类的上下文,则必须仔细阅读几次,以弄清其中的依赖关系以及它们如何组合在一起。 就像没有介绍的文章一样,这会浪费读者的时间,并且在其他开发人员(或将来的您)尝试更改某些内容时会导致错误。 这就是为什么我绝对建议在每个类(或复杂方法)上使用一个大的注释块,以实质上描述该代码的用途。 每段文字都需要一个简介,为什么一个班级会有什么不同? 永远记住,代码的读取远不止于编写。 针对读者而非作家进行优化。
由于RxSwift,全球许多iOS开发人员都使用了Reactive编程。 而且,如果您也使用它,那么您将习惯于编写Variables 。 好吧,我最近了解到,这个广受欢迎的BehaviorSubject包装器已经过时了。 此折旧尚处于初期阶段,目前不会发出任何警告。 但是,该路径已经布置好了,并且选择了其后继者: BehaviorRelay 。 为什么? 根据Krunoslav Zaher的说法,出于许多有关Variables的原因: 它不是标准的跨平台概念,因此在RxSwift目标中不合适。 它没有事件管理的可扩展副本( PublishRelay )。 它仅对状态建模。 它的命名与*Relay不一致 与RxSwift的其他部分相比,它的内存管理模型不一致(在dealloc上完成) 那么这对我们的代码意味着什么呢? 好吧,这: 可变方式 现在变成: 行为中继方式 但是,完成这一迁移是最后一步。 实际上, BehaviorRelay位于RxCocoa中 ,因此需要import 。 但是,将导入添加到不需要应用程序相关组件的应用程序的低层中似乎有点奇怪。 Zaher先生在此问题中提出了这个问题,并建议“将*Relay和SharedSequence提取到自己的框架中”。 整个冒险过程应该在RxSwift的下一个主要版本中结束。 *Relay类是RxSwift 4引入的。与BehaviorSubject不同,该ObservableType不能因错误或完成而终止。 您可以在Minh Vu Nhat的这篇文章中阅读有关它们的更多信息。 到底 我亲自做出了决定,现在,它是Koolicar的iOS行业协会的标准,可以在不延迟编写新代码的情况下使用BehaviorRelay 。 由于已确定弃用,因此我认为使用此全新代码缓慢开始过渡很有用。 同时,我尝试迁移我在任务中可能且安全的情况下遇到的Variables (如果合适)。 这个想法是试图尽可能地平滑过渡。 最后,我不耐烦地等待BehaviorRelay位置的最终答案。 我想从独立于UIKit的实体中删除RxCocoa 。 2018年9月17日,星期一: RxSwift开发人员昨天发布了其4.3.0“RotWeiß”版本。 自从Playgrounds,示例项目和测试中删除Variable的用法以来,对Variable的弃用一直在进行。
尽管我在一家初创公司从事移动开发人员的全职工作,但我在空闲期间从未停止过自己制作应用程序。 在构建了许多辅助项目(iOS和Android应用程序)之后,大多数项目并没有得到解决。 甚至那些确实发布的用户也只有十个用户。 但是最近的一个项目7Web起飞并吸引了很多人。 这是奇怪的部分。 耗时不到30小时。 它教会了我很多东西,这就是我学到的东西。 这就是我们大多数人的生活想法。 不一定是这样。 保持简单 您是否有一个雄心勃勃的想法,它具有巨大的潜力并且使您相信会产生重大影响? 嗯,在这种情况下,它比副项目更大,您必须对此更加热情,您需要组建团队并努力确保项目进展顺利。 但这不是附带项目。 它必须很简单。 我在以前的项目中犯了这个错误,这些项目规模巨大,我一个人呆了一年多。 这些项目现在回到架子上,收集灰尘。 尽管我在此过程中确实学到了很多东西,但它让我感到不满意,而且这肯定不好玩。 解决个人的小问题 一旦将标准设置得足够低,为您的副项目找到一个想法可能比您想的要容易。 这个想法的目的是解决问题。 问题可能是如此之小,以至于您甚至不敢称其为问题。 您可能是全世界唯一一个遇到此“问题”的人,但这并不重要。 找到这样的“问题”,您的项目就是解决方案。 即使您是百万分之一,也有7,000个像您一样。 就我而言,我在手机上阅读技术新闻时遇到了问题。 我每天阅读大约5到6个网站(例如“ TechInAsia”,“ TechCrunch”,“ The Verge”等),但发现打开电话(iPhone的Safari)上的许多标签确实非常困难。 “ 7Web”是我想出的解决方案。 一个简单的应用程序,以可滑动的方式放置我所有喜欢的网站,并一次性加载它们。 学习新技能 找到想法后,下一步就是实施。 如果您是一名程序员,那么应该很幸运,可以通过编写一堆代码来轻松解决问题。 没有多少人拥有此特权,并且不会将您的技能视为理所当然。 此外,此类项目对于您来说是学习新技能的绝好机会。 它可能是您想学习的新技术(也许看到了关于区块链的炒作),也可能是一种新的语言,但是您必须走出自己的舒适区来构建这个项目。 如果您不学习任何新知识,那么它就达不到目的。 作为iOS开发人员,我一直想抛弃“ Storyboard”,并使用代码(Swift)编写完整的UI。 我还想学习我在项目中所做的反应式编程(RxSwift)。 这是一次很棒的学习经历,我也可以在日常工作中重用这些技能。 使事情井井有条 这可能是我从该项目中学到的最重要的一课。 组织和计划您的项目绝对重要。 仅仅因为这是您的项目,并不意味着它必须快速而混乱。 从积极的一面看,您是您自己的项目经理。 使用Asana和Trello之类的工具来跟踪项目并确保遵守截止日期 。 即使您编写的代码也必须组织得井井有条,并且您应该有足够的信心将其开源(即使您选择不开源),也要记住这不是hackathon项目。 分享你的想法 尽管您的想法可能完全是愚蠢的,但不要回避与他人共享它。 一方面,它可以帮助您获得一些反馈。尽管目标是学习和娱乐,但获得一些反馈并没有什么坏处。 […]