协议定义了特定任务或功能的方法,属性和其他要求的蓝图。 然后,该协议是一项必需的任务,然后可由类,结构或枚举采用以提供这些要求的实现。 当一种类型满足要求时,就称其符合该协议。 句法 协议也遵循与类,结构和枚举类似的语法- 协议SomeProtocol { //协议定义 } 在类,结构或枚举类型名称之后声明协议。 也可以具有单个和多个协议声明。 如果定义了多个协议,则它们必须用逗号分隔,如以下示例所示: struct SomeStructure:Protocol1,Protocol2 { //结构定义 } 当必须为超类定义协议时,协议名称应在超类名称后加上逗号。 例如: class SomeClass:SomeSuperclass,Protocol1,Protocol2 { //类定义 } 协议可以具有存储或计算的属性,实例或变异方法或功能。 但是,如果它们是计算属性,变量实例或变异函数(不带花括号),则不能使用常量而是使用var (变量)来声明它们以符合协议。 此外,协议是类型,其名称以大写字母开头。 根据Apple文档: 协议不仅是一种类型,还可以扩展,它们可能要求特定的初始化程序通过符合类型来实现,并且总体上需要针对符合性类型的更多功能或各种规范。 在实现设计模式或委托时,Swift开发人员经常使用协议。 委托是一种设计模式,使类或结构可以将其某些职责移交给(或委托 )其他类型的实例。 根据Apple文档: 通过定义封装委托职责的协议来实现此设计模式,以确保符合类型(称为委托)可以提供已委托的功能。 委托可用于响应特定操作,或从外部源检索数据而无需了解该源的基础类型。 一个iOS开发人员经常会遇到的协议和委托模式的示例是在将TableView实现为常规ViewController时。 UITableView对象必须具有充当数据源的对象和充当委托的对象。 通常,这些对象是应用程序委托,或更常见的是自定义UITableViewController对象。 尽管它们有许多可选方法,但要完全符合Apple文档的DataSource协议,始终需要两种方法: tableView(UITableView, numberOfRowsInSection: Int) 需要。 告诉数据源返回表视图给定部分中的行数。 func tableView(UITableView, cellForRowAt: IndexPath) 需要。 要求数据源在单元格中插入表格视图的特定位置。 换句话说,当插入,删除或重新排列表的行时,数据源提供UITableView构造表和管理数据模型所需的信息。 除了数据源之外, UITableView对象的委托人还必须采用UITableViewDelegate协议。 委托管理表行的配置和选择,行重新排序,突出显示,附件视图以及编辑操作。 […]
第6章:DispatchGroup和OperationQueue 最近,我不得不做一堆异步任务,我只想在所有任务完成时得到通知。 该博客将介绍两种简单的方法:DispatchGroup和OperationQueue。 在这篇文章中,我们将同时介绍它们。 派遣组 如果您正在开发一个不使用Operations的项目,并且不想重构任何现有代码,则DispatchGroup是一个功能强大的API,可以将这些任务组合为一个任务。 情况1 :计算三个不同线程上三个数组的总和,一旦所有线程完成其执行,我想使用该结果。 在考虑解决方案之前,让我们学习一些与调度组相关的API。 enter () —明确指示一个块已进入该组。 leave () -明确表示该组中的一个块已经完成。 func notify (qos:DispatchQoS =默认值,标志:DispatchWorkItemFlags =默认值,队列:DispatchQueue,执行工作:@escaping @convention(block)()-> Swift.Void)– 当一组先前提交的块对象完成时,将要计划的块调度到具有指定服务质量类和配置的队列中。 解决方案 :这三个API将帮助我处理上述情况,让我们学习如何使用它们。 我在下面写了添加数组元素并返回的函数 此函数使用DispatchQueue.global()。async创建线程,并使用DispatchQueue.concurrentPerform创建循环以添加infoArr的所有元素(类似于for循环),然后返回名为block()的完成处理程序。 下面的函数将创建三个并行计算总和的线程,一旦线程完成,它将调用dispatchgroup的notify函数。 调用notify函数后,我们将拥有所有三个数组的和,并且我们可以将其传递给completeizationBlock()。 操作和操作队列 它是一个抽象类,您需要对其进行子类化才能使用。 如果您只想执行一小段代码或调用一个方法,则可以使用BlockOperation和NSInvocationOperation代替子类化Operation。 情况2:使用操作计算三个不同线程上三个数组的总和,一旦所有线程完成其执行,我都想使用该结果。 解决方案:创建OperationQueue实例以添加操作,创建三个BlockOperation以添加数组的总和,然后在操作之间添加依赖项(因为我们需要获得实际上不依赖的最终总和),一旦我们以任何顺序将这三个块操作添加到操作队列中,这无关紧要,在第三块上注册完成块以获取最终总和。 输出:下图显示-调用块的顺序和最终求和结果 有障碍的并发队列 并发队列中的任务可以任何顺序执行,并且可以同时启动。 与上述串行队列相比,这是非常快的。 但是,由于我们可能在写书的同时阅读,所以我们会遇到读者-作家问题。 如果有一种方法可以确保在读取时不进行写入操作,而在使用并发写入时不进行读取操作,该怎么办? 好吧,有一种方法可以使用带有Barrier的Concurrent Queue 。 如果我们采用上面的并发代码,并为写操作插入一个障碍,那么我们将确保在执行队列中的所有读取之后进行写操作,并且确保在写入时不会发生任何读操作。 使用带有障碍的并发队列可以帮助我们改善和加快代码的速度,同时消除读写器问题,这对于单例来说也很重要。 奖励时间:#import和@class之间的区别 “ #import”将整个有问题的头文件带入当前文件; 还包括该文件#imports的所有文件。 另一方面 , @class (当单独使用带有某些类名的行时)告诉编译器“嘿,您很快就会看到一个新令牌; 这是一堂课,所以要这样对待)。 当您有可能使用“ […]
对于不认识的人,OpenCV是计算机视觉开放源代码库。 它是用C ++编写的,这意味着您几乎可以在任何地方使用它。 从桌面应用程序到移动应用程序。 简而言之,OpenCV是: OpenCV(开源计算机视觉库)是一个开源计算机视觉和机器学习软件库。 OpenCV的构建旨在为计算机视觉应用程序提供通用的基础结构,并加速在商业产品中使用机器感知。 作为BSD许可的产品,OpenCV使企业可以轻松地使用和修改代码。 尽管创建新项目并添加pod或框架不是通常的任意任务,但考虑到它的好处,这是一个相当简单的过程。 首先,您可以克隆包含我们将在此处执行的操作的存储库。 在这个项目中,我们将从手机的摄像头获取视频流,并对其应用一些简单的色彩效果,仅用于演示目的。 因此,您需要将必需的权限添加到您的info.plist文件(即NSCameraUsageDescription 。 我们将添加OpenCV框架并将其与Swift一起使用。 首先创建一个项目(du!)。 然后初始化pods: $ cd project_root_directory $ pod init 然后将框架添加到您的Podfile : pod’OpenCV’,’〜> 3.1.0.1′ 不要忘记打开由CocoaPods创建的工作区,而不是打开您创建的项目。 OpenCV对称为Mat的n维密集数组数据类型(而不是UIImages 。 因此,我们需要一种在两者之间进行转换的方法。 为此,我们UIImage添加扩展 UIImage + OpenCV.h UIImage + OpenCV.mm 不要错过.mm扩展名。 它表明它是一个Objective-C ++文件,因此XCode以此进行编译。 否则它将无法正常工作。 接下来,我们将创建一个类,用于从相机获取图像流以进行处理: OpenCVCam.h OpenCVCam.mm 上面的类初始化相机,并处理每一帧。 它没有做任何花哨或复杂的事情,但对于初学者来说,这很好。 好了,图像已处理。 现在怎么办? 现在,我们必须在视图控制器中获取图像,或者将其实际使用或呈现。 为此,我们定义了一个委托(在OpenCVCam.mm ): OpenCVCamDelegate.h 到目前为止并不难,不是吗? 好的,我们差不多完成了。 不过,有一个很小的问题。 […]
不久前,我将Xcode转换为Xcode 8,这最终意味着我可以选择将整个项目转换为Swift3。虽然大多数转换是为您完成的(其中很多是对您而言),但是仍然有一些组件Xcode不能更改,您必须手动检查代码以自行查找和转换它们。 由于Swift 3上个月才问世,因此您在网上找不到太多的文档/语法,因为大多数人仍在使用它或尚未转换。 我发现有些东西与Swift的早期版本和Swift 3有所不同。其中之一是大多数“ NeXTSTEP”类都消失了。 “ NeXTSTEP”或NS — — —是Objective-C类,是可可框架的原始代码。 在进行API调用时,我记得在转换为Swift 3之前,我必须使用NSURL来获取URL并使用NSURLSession来创建互联网会话。 现在有了Swift 3,API调用的NS部分已经消失了,现在仅使用URL和URLSession。 我发现,尽管仍然有一些使用NS的类(例如NSDictionary,NSArray等),但Apple试图让他们的语言Swift摆脱NS。 我必须自己手动更改的另一个组件是实现核心数据时。 在Swift 3之前,我记得在获取数据时,我们必须将获取请求置于需要获取的任何对象上。 func fetchData() { var错误:NSError? =无 让userRequest = NSFetchRequest(entityName:“ Users”)做{ 让对象=尝试ManagedObjectContext.executeFetchRequest(userRequest)作为? [用户]如果对象?.count> 0 { 如果让对象=对象 { 个体=对象[0] } } }赶上{ 打印(错误) } 在Swift 3中,他们在获取请求后使用该胡萝卜符号,有点像将其包围在需要的对象上。 现在,将项目转换为任何版本的Swift或Xcode时最令人沮丧的一件事是,如果您在项目中使用了CocoaPods。 短期内,CocoaPods是来自其他程序员的第三方代码段,以多种方式帮助您的项目,例如动画,设计,颜色,方法调用,API,约束等等。 在项目中使用CocoaPods的问题在于CocoaPod必须支持您正在使用的版本。 因此,如果您在Swift 2.3中处理项目,那么CocoaPod也必须在Swift 2.3中。 由于Swift 3还是相对较新的版本,因此并没有很多CocoaPod更新到Swift 3,这使得您的项目无法运行,直到他们对其进行更新,或者您在项目中手动进入其源代码并将其转换为Swift 3。 最终,所有Swift程序员都将不得不转换为Apple提供给我们的最新版本,即使您遇到190编译错误,我们作为程序员也必须咨询这些更改。 不要害怕更改,这是非常有益的,因为您可以从Apple获得最新版本和更新,并且Apple所做的这些更改旨在帮助我们Swift程序员使您的程序运行起来更流畅,更容易编码。
如前一篇文章中所述,在进行团队开发时,故事板可能不是最佳解决方案。 但是如果没有情节提要,您如何实例化视图? 这是我将在本文中讨论的主题。 如何从XIB文件实例化视图 创建一个“ Xibview.swift”文件。 这将是一个便利类,能够从xib文件创建视图。 从现在开始我们创建的每个UIView都将实现“ Xibview”。 “ initViewFromName”负责创建视图。 它会… 接收一个UIView类,并提取其类名。 从类名生成一个笔尖。 从笔尖实例化视图。 对于那些想知道笔尖/ XIB有何不同的人,它们在功能上是相同的。 笔尖是二进制文件,而xibs是xml格式,因此在集成诸如GitHub之类的版本管理系统时,xibs是首选。 创建一个xxxView.swift,它将是您的xib文件的文件所有者(我们将在下一步中创建)。 类名无关紧要,但是请确保它继承了XibView,即我们上面刚刚创建的类。 创建一个xib文件。 将我们在上面创建的类指定为文件的所有者。 该文件的所有者(通常)是用于在运行时访问xib文件的类。 更改背景颜色可能是一个好主意,以便您知道何时正确显示视图 意识到! 确保“ xib文件”和“类名”具有相同的名称。 为什么? 因为XibView(我们创建的)只能从其类名实例化xib文件。 准备完毕! 就这样! XibView将处理所有实例化并将全尺寸视图添加到ViewController。 以下是如何创建此视图的示例: 初始化此ViewController时,还将初始化我们创建的视图。 视图初始化器不是用类本身编写的,因此XibView会处理它。 通过在loadView()中设置self.view,我们告诉ViewController要显示哪个视图。 一些陷阱 从xib创建视图时有一些陷阱。 例如… 这是一个坏主意。 你能猜出为什么吗? 好吧,让我们看看如果运行该程序会发生什么。 EXC_BAD_ACCESS…。 这并没有多大帮助,但请看一下堆栈跟踪。 我们有一个整齐的无限循环! 当为“视图”本身(而不是文件的所有者)分配了自定义视图类时,将在每个xib实例化时调用自定义视图类中的初始化代码。 但是在初始化代码中,我们正在从xib实例化一个新视图。 实例化此xib时,将调用我们自定义视图的init代码。 但是在初始化代码中,我们正在从xib实例化一个新视图。 实例化此xib时,将调用我们自定义视图的init代码。 但是在初始化代码中……。 你得到其余的。 摘要 在本文中,我解释了 如何从xib文件创建视图 […]
在本文中,您将简要了解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的软件设计师
我们只用一台iPad做到了。 想像一下我们可以做什么2。 “最后,我们只为没有抓住机会感到遗憾。” 令我感动的是,我永远不会忘记那一刻在旧金山机场的那一刻,我的脸上露出笑容,并为那些等待我到达卢旺达教他们快速编程语言的孩子们感到内心的喜悦。 错过我上学的第一个月是一个艰难的选择,以便我可以向这些英雄孩子们教授快速的编程语言,但是从来没有比这更好的时间了,这要感谢苹果发布了Swift Playgrounds,他们做到了每个人都可以轻松地在iPad上,尤其是发展中国家的孩子们学习如何编码。 多年来,我一直有这个主意,尽管我不知道在快速操场之前会教哪种技术,但现在我必须决定是否要帮助塑造我积极成长的世界,还是留下来。 因为我的学期已经开始,所以我花了一个周末试图确定是否是合适的时间。 我一遍又一遍地观看“疯狂的人在这里”的视频,除了走动,别无他法。 坐在硅谷公寓的沙发上,日落时正看着窗外,就在那儿,我知道如果我借此机会去分享灵感,与这些孩子们在一起并帮助他们看到他们的潜力和能做什么,他们可能是推动人类前进的未来创新者。 他们可能有一天更早地改变非洲,发明有一天我们可能会喜欢的先进技术。 我不得不去。 我不能再否认了。 激情不仅仅是留下的意志。 我宁愿回头说“我不敢相信我做到了”,而不是“我希望我做到了”。我预定了飞往卢旺达的航班,以进行为期20天的代码项目。 我在土耳其伊斯坦布尔停留,追赶2015年在印度旅行时认识的土耳其朋友。 接下来的两天,我离开了土耳其,尽我所能去做:教6-14岁的孩子如何用Swift编写代码。 他们是快速学习者,对技术充满热情。 每当想到这些小孩子眼中的欢乐时,我的心都会融化。 令我惊讶的是,一个iPad如何改变了大约40个孩子的生活,激发了他们的积极性,并睁大了他们的眼睛,梦想更大,更远大。 他们具有改变世界的潜力,一次只需要一行代码。 他们只是从来没有机会做过像编码这样的事情。 他们总是准时,从不迟到,总是为学习更多而兴奋。 我很受启发。 是他们发光的时刻; 我喜欢它的每一点。 等一下加斯顿! 您如何在一个地方找到这些孩子? 注意:这些是由act4Rwand.org首席执行官兼创始人Lynda Weir赞助的学生。 在我离开之前,我与卢旺达教育部的技术部长(ICT)联系,教孩子们如何编码。 他对我的想法非常理解,随和和欢迎。 因此,我们计划尽快启动该项目。 在我们卢旺达的教育系统中,这将是最快捷的途径。 但是,我仍然想尝试一下这个想法,看看孩子们会如何享受它。 那时我联系了act4rwanda.org的首席执行官兼创始人Lynda女士,询问她如何使用act4rwanda的设施,在那里她帮助了无法继续教育的孤儿和弱势的卢旺达儿童。 她非常不可思议,非常善良,并且爱人。 她花费时间和资源支持这些孩子,以便他们拥有更美好的未来。 如果不是她,我将找不到这些聪明的孩子。 他们是她的孩子,他们叫她妈妈Lynda :) “灵感来了……” 如果我没有从启发我去做这个项目的开始,那可能不会有太大帮助。 2015年,我在印度KiiT计算机工程学院学习海外。 该学校有25个校区,还有一个大的部落孩子校区,他们帮助他们从基础到高等教育接受免费教育。 那只是25,000个孩子,他们渴望学习任何可以教给他们的东西。 当我自愿教他们法语时,令我惊讶的是:这些孩子学得很快。 他们可以捕获并完美发音许多法语单词,这对于几乎所有母语不是法语的人来说都是非常困难的。 我想在2015年12月离开印度,想做更多的事情。 我想有一天回去再次当志愿者,但我有学校责任。 那是我想到20天代码的想法,后来成为一个有趣的项目的时候。 我在整个学习过程中都很幸运; 我知道一项重大技术会影响世界,因此我努力回馈社会。 “给谁很多,将需要很多。” 改变世界,让世界更美好需要我们所有人。 […]
Swiftify提供了多种将Objective-C代码转换为Swift的方法。 如果您使用AppCode而不是Xcode进行开发,则可以使用Swiftify的AppCode插件直接从编辑器中转换代码行或整个文件的选择。 优点 AppCode的可扩展性使其成为一个理想的IDE,可将您的Objective-C项目逐步迁移到每个文件的Swift。 它使您能够: 同时转换.h和.m文件对,与Swiftify的Xcode扩展名不同,由于Xcode Source Editor扩展名的限制,Swiftify的Xcode扩展名一次只能处理一个文件。 借助内置的AppCode项目文件解析器,自动更新Xcode项目文件。 无需离开AppCode或使用外部工具即可完成整个转换。 安装插件 要安装Swiftify AppCode插件,请转到AppCode菜单,然后选择首选项 。 从侧面板中选择插件 ,然后选择底部的浏览存储库按钮。 搜索“ Swiftify”,然后单击“安装”按钮。 最后,重新启动AppCode以开始使用插件。 入门 在开始将代码转换为Swift之前,您需要添加API Key 。 转到Swiftify扩展页面,然后复制您的API密钥。 返回AppCode,打开AppCode> Preferences ,选择Tools ,然后快速化并粘贴您的API密钥。 在AppCode中打开您的应用,然后选择一个Objective-C类开始对其进行转换。 将Objective-C类转换为Swift AppCode插件可让您将代码行或整个文件中的一部分转换为Swift。 选择一些Objective-C代码,右键单击它,然后选择Swiftify> Convert Selection to Swift 。 您也可以通过单击“ 工具”菜单,然后选择“ Swiftify”来访问相同的选项。 要转换整个类,请从项目窗口中选择.h和.m文件,右键单击它们,然后选择Swiftify> Convert [FileName] to Swift 。 Swiftify将创建一个新文件,其中包含来自Objective-C标头的所有类和方法以及您选择的实现文件。 请注意,在这种情况下,Swiftify不会生成Objective-C桥接标头,因此,如果新生成的Swift代码使用Objective-C类,则需要手动创建桥接标头。 为了能够构建项目,请选择旧的.h和.m文件,右键单击它们,然后选择从Xcode项目中排除 。 这将从项目文件中删除对这些文件的引用,但会将它们保留在项目目录中,以防您需要再次返回它们。 确认一切正常后,可以继续从项目目录中删除旧的.h和.m文件。 选择下一个要转换的Objective-C文件,然后执行相同的步骤。 如果遇到错误,表明您的项目对刚转换的类的某个体系结构具有未定义的符号,请确保选择“运行”>“清理构建文件夹” ,然后再次构建应用,以进行清理构建 […]
最近,我开始使用相当大的iOS / Swift代码库,该库需要几分钟才能从一个干净的文件夹完成完整的构建。 由于我手头上有多个macOS工作站,因此我自然地好奇如何将它们与我最常见的用例(开发Swift iOS应用程序)进行比较。 有没有能让我在整整一整整的时间内少拿一杯咖啡的时间? 代码库 我用于这些测试的代码库具有以下配置文件: Swift文件: 223 Objective-C文件: 6 故事板: 35 Xcode版本: 8.3.2 安排:一个主要目标,有两个嵌入式项目。 测试方法 我使用的方法非常简单,围绕Xcode开发的计算机“实际使用”进行设计: 清理项目,手动删除整个DerivedData文件夹。 关闭电脑 重新开启电脑 打开项目 选择“通用ios设备”目标OS,然后构建项目(措施1) 清理项目,关闭Xcode,手动删除DerivedData(再次) 启动Xcode,再次构建项目(测量2) 我计划进行两次试验,以记录构建当前不在磁盘缓存中的项目的经验,然后在 macOS有机会将文件保留在磁盘缓存中之后再次构建它。 如下数字所示,这对两台基于SSD的计算机几乎没有影响,但对于具有Fusion磁盘的iMac却产生了巨大影响 。 对于所有试验,我确保计算机都使用交流电源,没有其他应用程序在运行-实际上,自启动每台计算机以来,除了运行XCode计时测试之外,我什么都没做。 我使用以下所述的三台不同的计算机进行了测试。 2015 15英寸(Retina)MacBook Pro Core i7 测试对象1是2015年的MacBook Pro,配备Core i7 CPU,SSD和16GB RAM。 这是许多认真的开发人员都会选择的非常标准的“开发人员工作站”。 实际上,我的测试确实支持这可能是开发人员(三个测试对象中)在功能和便携性之间的最佳平衡。 2015 27英寸(5K)iMac Core i5 测试对象2是2015年的iMac,配备Core i5 CPU,Spinning Fusion驱动器和32GB RAM。 这是我的“每日驱动程序”开发工作站。 虽然对于开发人员来说,带有旋转磁盘的Core […]
Em muitos casos,nossasaplicaçõessãopequenas e salvam 1,2 talvez 3 dados。 Estes dados podem ser pequenos e简单类,自定义类和自定义类,在没有用户默认值的情况下,使用编码器。 徽标Google的相关信息,以及框架数据的框架,以及框架数据和核心数据。 Tudo is so para salvar um objeto com 2 ou 3 campos。 用户可使用简单的格式或用户默认值。 Primeiro vamos criar uma classe que pode ser“persistível”。 顺便提一下,对象是NSObject和NSCoding: Esta nossa classe Pessoasópossui um atributo / propriedade chamada nome。 Mas elenãoéobrigatório,克里,作为procedades quevocêquiser。 解码器在解码器中起作用。 示例,条件,条件: 重要说明:解码或解码正确的代码(解码或整数)。 Agora […]