Tag: 编程

iOS开发部分-6

迅捷数组 在本教程中,您将学习数组,创建数组,访问数组的值以及数组中的一些常见操作。 目录 1.什么是数组? 2.如何声明数组? 2.1声明包含重复值指定数量的数组 时报 3.值如何存储在数组中? 4.修改数组元素 4.1整体修改数组 4.2添加新的数组元素 5.一些有用的内置数组函数和属性 5.1 isEmpty 5.2首先 5.3附加 5.4插入 5.5移除 5.6倒转 5.7个 在之前的Swift Data Types文章中,我们了解了如何创建可以容纳单个值的某些Data Type的变量/常量。 但是,如果我们要存储相同数据类型的多个值怎么办。 我们在Swift中使用了一个叫做Array的东西。 什么是数组? 数组只是一个容器,可以在有序列表中保存一个数据类型的多个数据(值),即,您以与定义数组中的项相同的顺序获得元素。 数组可以存储任何数据类型的值,例如Int , String ,class等。 如何在Swift中声明数组? 您可以通过在方括号 [] 指定数据类型来创建一个空数组 。 请记住,您必须在方括号内包括类型,否则Swift会将其视为普通数据类型,并且您只能在其中存储一个值。 声明一个空数组 有三(3)种方法可以在Swift中创建空数组,而速记语法方式始终是首选。 方法1:速记语法 var arr = [Int]() 方法2:数组初始化 var arr = Array() 方法3:具有数组文字的数组 var arr:[Int] = [] […]

iOS开发第-3部分

Swift数据类型 目录 什么是数据类型? 数据类型的大小 Swift数据类型 –布尔 –整数1)整数8和2) UInt –浮动 –双 –人物 –弦 要记住的事情 1.什么是数据类型? 数据类型是变量或常量可以存储在其中的数据(值)的类型。 例如,在文章Swift变量和常量中,您创建了一个变量和一个常量以将字符串数据存储在内存中。 该数据可以是文本/字符串(“ Hello”)或数字(12.45),也可以是位(0&1)。 定义数据类型可确保仅存储定义的数据类型。 让我们看一个场景: 假设您要创建一个游戏。 由于大多数游戏在游戏完成后都会显示高分和玩家姓名,因此您需要为游戏存储这两个数据。 高分是一个数字(例如59),而玩家的名字是一个字符串(例如Jack)。 您可以创建两个变量或常量来存储数据。 在Swift中,这可以通过将变量和数据类型声明为: var highScore:Int = 59 var playerName:String =“杰克” 在这里,我们声明了存储值59的Int类型的highScore变量。并且,声明了存储值Jack的String类型的playerName变量。 但是,如果您执行以下操作: var highScore:Int =“杰克” 您将得到一个编译时错误,指出无法将’String’类型的值转换为指定的’Int’类型 。 这是因为您声明highScore存储整数值,但在其中放置了字符串。 此错误可确保highScore只能存储一个数字,而不能存储玩家的姓名。 数据类型的大小 数据类型的另一个重要部分是其大小。 这指定了可以存储在给定变量或常量中的数据大小。 Type的大小以位为单位进行测量,最多可以存储2bits的值。 如果您不了解Bit,请将其视为0或1的值。 因此,对于Type size = 1位,它最多只能存储21 = 2,两个值:0或1。因此,字母程序的1位系统可以将0解释为a / 0,将1解释为b / […]

Swift中的可重用性和组成

尼采,梭罗和黑森最有可能试图逃避他们一生的一个概念:依赖性。 即使一个人不同意或拥护他们的哲学,程序员应该还是必须? -在编程时运用他们的思维方式。 让我们先定义问题: 耦合 想象一下,没有一部可以拆卸的汽车。 从座椅到车轮,从底盘到天窗都是一体的。 如果由于在高速公路上钉了一些讨厌的钉子而使轮胎漏气,我不能只买新轮胎,就需要买一辆新车。 因此,我们将此设计称为耦合设计,或者以一种更真诚,更礼貌的方式进行; 愚蠢的设计。 编程没有什么不同。 如果某个类或功能的更改需要我重构程序的许多其他部分,那么我已经设计了这款不可拆卸的汽车。 不酷 一点都不酷。 那么,当我们意识到我们的代码紧密耦合时,我们该怎么办? 我们花了片刻的沉默。 我们意识到我们编写了一些糟糕的代码,并宣誓不再这样做。 靠这些话活着: 封装 , 单一责任和继承构成 。 我将以一些简单的示例开始,这些示例说明了我们如何在程序中尊重这些概念,然后将其构建为相当(但不是真的)复杂的示例。 钢琴家或小提琴家 您的功能签名应严格执行其声称的功能; 不多一点。 让它成为钢琴家或小提琴家,而不是两者。 所以我有一个函数应该打印字符串中某些字符的数量: func printNumber(of char:Character,in string:String?)} 如果让string = string { var count = 0 对于字符串{中的s 如果s == char {count + = 1} } 打印(数) } } 此功能做不到预期的。 如果为空字符串,则不打印任何内容,而应打印“ 0”。 […]

闪电阅读#1:Swift中的懒惰收藏

我打算暂时就Swift的日常实验写一些关于我的发现的“简短”文章……🕵 这是第一篇闪电文章! 🚀 问题:地图,flatMap和过滤器功能随附的中间杂波 假设我们在一个假想项目中具有以下要求: 可以下载6帧格式为animation_.jpeg 。 –使用Request对象下载动画帧。 –丢弃第二帧以获得更好的性能。 在现实世界中,我们很可能会有更多的帧,但可以将其视为简化示例。 我们将不使用这6帧的for循环,而是使用map , flatMap和filter方法。 让frameIndexes:[Int] = Array(1 … 6) 让imageRequests:[请求] = frameIndexes //通过每隔一帧过滤进行优化: .filter {$ 0%2 == 1} //将帧号转换为图像名称: .map {“ animation _ \($ 0).jpeg”} //将图片名称转换为网址: .flatMap {URL(string:“ https://www.somehost.com/\($0)”)} //转换网址以请求对象: .map {Request(url:$ 0)} 这比具有for循环更具可读性。 但是性能如何? 让我们逐行遍历此代码块来详细研究。 filter块对数组中的每个帧索引运行6次。 使用3个过滤的帧索引创建一个新数组。 每个图块运行3次。 将使用3个图像名称创建一个新数组。 flatMap块对每个项目运行3次。 将使用3个URL创建一个新数组。 (假设将在每个图像名称上成功创建URL。) map块在每个URL上运行3次。 使用3个请求对象创建一个新数组。 呼叫顺序将如下所示: […]

使用Swiftify更好地发送消息

许多开发人员在初次尝试使用该语言时就对Objective-C的消息发送语义感到困惑。 消息发送的语义使得可以“调用”空对象上的方法。 您实际上并不是在调用方法,而不是将消息发送到没有地址的地方。 如果您是在Swift中构建应用,则不必担心理解Objective-C消息发送。 这就是为什么最新版本的Swiftify的Objective-C至Swift Converter大大改进了我们处理消息发送的方式。 在Objective-C中,属性只是方法周围的语法糖,可以像调用方法一样调用它。 @implementation TestViewController:UIViewController-(IBAction)graphButtonClicked:(id)sender { GraphViewController * graphViewController = [[[[self splitViewController] viewControllers] lastObject]; }@结束 注意对[self splitViewController]而不是self.splitViewController 。 在Swift中,您不能引用self.splitViewController()因为该方法不存在。 我们的转换器按预期处理此问题: 类TestViewController:UIViewController { @IBAction func graphButtonClicked(_ sender:Any){ 让graphViewController = splitViewController?.viewControllers.last as? GraphViewController } } 对[self splitViewController]属性getter的调用将替换为Swift中适当的属性调用。 甚至splitViewController的可选性都是正确的! 您可以在此处测试示例。 Objective-C如何处理方法和消息还有另一个有趣的方面。 Objective-C方法的参数名称不是方法签名的一部分。 @interface TestViewController:UIViewController -(NSString *)greetPerson:(NSString *)personName; @ end @ implementation TestViewController:UIViewController-(NSString *)greetPerson:(nonnull NSString […]

C静态库101

命令: gcc -c * .c 该命令的输出是源.c文件的目标文件。 默认情况下,源文件的目标文件名是通过将后缀.c , .i , .s等替换为.o来实现的 。 现在,每个源文件都有它的目标文件。 2.现在,让我们创建静态库libtaticlibrary.a并将目标文件的副本放入其中。 命令: ar rc libtaticlibrary.a * .o “ ar” —存档器。 “ c”标志表示“ ar”必须创建(如果尚不存在的话)。 “ r”标志确保使用新的目标文件替换库中较旧的目标文件。 我们刚刚创建了一个静态库名称“ libtaticlibrary.a”。 3.索引您的存档。 编译器将使用索引来更快地查找库中的符号。 它还可以确保在编译期间库中符号的顺序无关紧要。 命令: ranlib libstaticlibrary.a 如何使用静态库 创建库后,可以在程序中使用它。 命令: cc files.o -L。 -lstaticlibrary.a -o执行文件 其中-L。 告诉链接器在当前目录中查找静态库lstaticlibrary.a ,将其链接到程序并将所有内容打包到可执行文件execfile中 。

用委托模式分离问题

在上一篇文章中,我们讨论了Closures的语法以及如何在其接收函数中使用它们。 今天,我们通过确保视图尽可能与控制器分离,来研究一种可用于在应用程序中实施分离和可扩展性的技术。 什么是代表? 委托模式被认为是解决关注点分离的一种可能解决方案,即任何对象都应处理自己的独特问题集。 例如,矩形结构不应处理计算圆的面积,依此类推。 这是一个非常明显的例子,但是委托的思想是一个对象应该使用专门的帮助对象来完成一项任务。 在MVC中,视图应负责向用户显示内容。 由于用户将通过单击,点击或按下视图来与视图进行交互,因此它们还必须接收输入事件。 但是,控制器的责任是实际解释输入并决定采取什么措施来响应输入,这是我们需要真正考虑设计的地方。 那么,如何在不使其中一个过于依赖另一个实现的情况下将视图的输入传递给控制器​​? 我们可以认为Controller在这方面是代表吗? 让我们从代码开始 让我们看一下我们将用于实验的类。 这是我们的BaseController,当我们要扩展应用程序时,它指定了一些不错的功能: 协议控制器{ 关联类型ViewType var typedView:ViewType {get} } class BaseViewController :UIViewController,控制器{ 覆盖func loadView(){ self.view = ViewType() } var typedView:ViewType { 如果让view = self.view为? ViewType { 返回视图 }其他{ 让view = ViewType() self.view =视图 返回视图 } } } 这是我们的BaseView,它为我们的View执行相同类型的操作: BaseView类:UIView { 便利init(){ self.init(frame:.zero) } 覆盖init(frame:CGRect){ […]

豆荚,迦太基和SPM:Swift的包装管理困境

到2019年,Swift已从Apple的少数几个开源项目之一发展成为一种功能强大的语言,成为Apple系统开发背后的强大力量,甚至还扩展到了Linux等其他操作系统。 现在处于4.2版中,期待已久的Swift 5发行版,Swift因其协议定位和为多个平台编写本机应用程序的能力而变得非常流行。 Swift 3是所有Swift用户和开发人员的标志性版本:它是代码破解版本,更改了大多数语法,删除了语言方面并添加了其他内容,并引入了其他主要工具和增强功能,例如Swift Package Manager和Swift Linux的核心库。 但是,随着Swift 3的到来,对开发人员来说,另一个艰难的决定。 Swift软件包管理器(Swift Package Manager)是Swift开发人员的第三个软件包管理器,但也是第一个正式软件包管理器,现已投入使用,使库和框架的选择和分发过程更加多样化。 Swift的包装管理困境 Google的词典将困境定义为“必须在两个或多个替代方案之间做出艰难选择的情况,尤其是同样令人讨厌的替代方案。”现在,我不会说所有可用的软件包管理器都是令人讨厌的,但我可以同意,它们都不是完美的。 与任何软件一样,程序包管理器都有其成功之处和不足之处,尽管每种缺点在开发中使用时都可能导致麻烦。 Swift的三个主要包管理器是Cocoapods,Carthage和Swift包管理器(SPM)。 Cocoapods是该小组中的老大,自从Objective-C是Apple的主要软件开发语言以来就一直存在。 Cocoapods最初于2011年9月17日发布,最初是为使用面向对象的C风格语言的库和框架提供服务的,为随之而来的软件包管理者铺平了道路。 当Swift成为主流时,Cocoapods慷慨地扩展到包括新语言的库和框架,新语言是其他程序包管理器将在以后建立的语言。 当2014年11月到来时,下一个软件包管理器发布了,这意味着Cocoapods不再是使用Xcode的那些的唯一发行商。 多种选择的能力都很强,这使得最初的Swift软件包管理器引起了争议。 尽管许多人认为它对Swift和Objective-C开发人员来说是革命性的,但其他人却因为它的明显缺点对其进行了轰炸。 Cocoapod最显着的功能之一就是它完全自动化了依赖程序,开发人员只需运行pod install ,Cocoapods便会获取并构建依赖项,将其插入项目中,将其链接到项目中,并生成一个包含两者的工作区。项目和豆荚。 事实证明,虽然该功能是主要的便利,但开发人员并不完全满意:尽管该过程确实节省了他们大量的时间和精力,但它也将对项目的控制权移交给了Cocoapods并让其处理文件和项目设置。 开发人员感到这是一种无声的痛苦,直到下一个程序包管理器发布时,这种痛苦才得以表达。 随着时间的流逝,开发人员对允许流行的第三方掌控为其项目构建程序包的满意度越来越低。 尽管较新的软件包管理器是用Swift编写的,但对于Swift而言,Cocoapods是用Ruby编写的,这意味着开发人员确实需要熟悉该语言才能操作软件包管理器。 许多人确实知道Ruby,而且学习曲线并不复杂,因此添加另一种语言的文件带来的不便并不麻烦。 但是,Swift的软件包管理器不是用自己的语言(例如Nuget,PyPi或NPM)编写的,而不得不使用另一种语言的事实给开发人员带来了痛苦。 Cocoapods是集中式的,这在软件包管理器中很常见(一个常见的指标是软件包注册表)。 程序包管理器中的集中化意味着存在一个中央代码注册表,可以在其中托管和查看程序包,并且客户端(通常是命令行界面)可以从中提取代码以生成程序包。 可以从cocoapods.org上浏览其网络上托管的所有Pod,这对于那些没有特定软件包或只想浏览可用软件包的开发人员来说非常有用。 但是,许多人似乎对新的分散化概念感到迷惑,这意味着Cocoapods不再是理想的包裹管理系统。 尽管Cocoapods有其缺点,并且最近一直受到嘲笑,但是它仍然是Swift的包管理器中最古老的,并且由于其自动化,对初学者非常友好。 CocoaPods.org iOS和Mac项目的依赖管理器 cocoapods.org 迦太基是第二位进入该小组的包装经理,从一开始它就与Cocoapods的主要区别显而易见。 它于2014年11月18日发布,在Swift 1.1正式发布后仅两个月就可用,并且支持Swift中的Objective-C。 迦太基在Cocoapods中发现了一个对开发人员来说很酸的话题:虽然Cocoapods是用Ruby编写的,但是Carthage完全用Swift编写了一个包管理器来迎合用户。 除了以Apple支持的语言以及您的项目被编写时,依赖管理的强大功能之外,Carthage还声称它利用Xcode的构建系统,同时为开发人员提供了集成其依赖的自由。 通过迦太基,开发人员可以控制他们项目的依赖关系,从而使他们能够在迦太基构建之后,根据自己的选择进行链接和管理。 第一次学习如何将Carthage集成到您的项目中(以及随后针对更复杂的需求)时,Carthage的README具有令人难以置信的描述性和实用性,但是对于经验较少的开发人员来说,开始使用它可能非常复杂。 但是,随着集成过程的延长,从长远来看,它将带来更多的简化和控制。 设置好迦太基并链接了依赖项后,只需要将一行添加到一个非常简单的文件(而不是将一行或多行添加到Ruby文件)和一个命令, carthage update ,就可以生成新的框架。可以导入原始文件的方式。 迦太基消除了在较大的.xcworkspace中处理多个.xcproject文件的麻烦,并消除了与核心项目一起添加的庞大文件结构,而仅在项目根目录中使用.framework文件夹对项目进行了补充,该文件夹清楚地说明了名称。框架。 迦太基提供了Swift,Objective-C或其他语言的其他软件包管理器所没有的某种程度的控制,那就是完全控制。 刚开始创建运行脚本并将框架链接到项目似乎很困难,但是一旦习惯后,该过程将变得异常顺利。 […]

在iOS体系结构中使用合成

我最近更新了我的一个旧的github项目,该项目大约是四年前我刚开始进行iOS开发时创建的。 这是使用容器视图控制器的示例,特别是我正在研究视图控制器之间的转换。 在该项目中,三个子视图控制器包含在一个视图控制器中,它们周期性地以逆时针方向旋转。 这是一个非常简单且人为设计的视图控制器包含示例,只是为了帮助我了解这种技术的工作方式。 在重新审视视图控制器包含区时,我发现了一些最近的博客文章和会议讨论,内容涉及在iOS中使用容器视图控制器来帮助分离关注点并防止使用大量视图控制器。 像Dave DeLong,John Sundell和Paul Hudson这样的人。 与最初开始开发应用程序相比,这使我想到了最初的实现以及现在如何构建iOS应用程序。 iOS我们一直使用Apple的容器,形式为UINavigationController , UITabBarController , UIPageViewController 和UISplitViewController 。 自iOS 5以来,自定义容器视图控制器就已经存在,并且由Apple实施,部分目的是防止他们认为滥用了应用程序中的视图层次结构。 当来自一个视图控制器的视图被“剥离”并放置在另一个控制器的视图层次结构中时,就会发生这种情况。 这导致许多视图控制器的外观和旋转方法未被调用,从而导致意外行为和不良的用户体验。 苹果的演讲可以在这里找到:WWDC 2011 —会话102。该解决方案相当简单,因为所有UIViewController类都具有旨在添加和删除子控制器的方法。 实际上,添加或删除子视图控制器时需要调用几种方法,这些方法可以在Apple的iOS的《 View Controller编程指南》中找到。 布局 UIViewController的内容视图仅使用代码进行Auto Layout ,不使用InterfaceBuilder也不使用Auto Layout 。 我想在这个例子中尝试一些不同的东西,所以我选择只是将视图放在代码中。 这在更复杂的视图层次结构中具有一些挑战,但也具有一些优点。 缺点是可能涉及一些复杂的数学运算,因为您需要手动计算每个视图的位置和大小。 在这种简单的层次结构中,这相对容易一些,但是在更复杂的视图中,您可能需要将屏幕划分为多个部分,手动构建这些视图,然后将所有视图组合在一起。 组合是编程中最强大,最重要的概念之一。 从好的方面来说,这意味着布局更改相对容易处理,没有添加/删除或调整的限制。 我们重写viewWillLayoutSubviews 并计算视图的框架。 每当旋转设备时,都会再次调用此方法,并相应地调整视图框架,这非常好。 希望您喜欢这篇文章。 在构建应用程序时,请尝试将构图积极地融入设计中。 即使只是将状态属性分离成枚举,创建新的类型来保存方法参数,封装网络代码或将视图创建代码移到单独的类中的小步骤,也可以使您的应用程序更易于理解和维护。 最终项目可以在这里找到:ViewControllerContainment 资料来源 [1] Dave DeLong博客 [2] SwiftBySundell [3]与Swift合作 [4]阴影图像 [5]图示8 […]

iOS开发日记-第2周

这次我的职位很晚,但是昨天德国在世界杯比赛中德国对墨西哥(0:1)的糟糕表现后,我非常疲惫。 我本周了解到… 视图和控件 自动布局,堆栈视图和尺寸类别 我这周最努力地与… 游乐场!!! 😠 如何修复永久运行的游乐场 我真的很喜欢Playgrounds,并且可以运行Swift代码并立即查看结果,但是本周我遇到了一些奇怪的行为。 打开新的Playground并编写一些代码后,Xcode突然崩溃,或者Playgrounds永久卡住。 我几次重新打开Xcode,但是每次都发生相同的问题。 我感到非常失望,因为我认为Playgrounds是探索Swift编程语言并让每个人都可以访问编程的好工具。 但是目前,结果恰恰相反。 经过研究,我想出了一个解决方案。 将Playground从自动运行更改为手动->按住左下角的小箭头 退出Xcode 在活动监视器中强制完全处理com.apple.coresimulator 重新启动Xcode 这应该可以解决问题,但是每次进行一些更改时都必须手动启动它。 了解更多信息。 Xcode游乐场卡在“运行游乐场”或“启动模拟器”上,无法运行… 每次我创建一个新的游乐场以测试一些代码时,Xcode都会卡住并且不会运行该代码。 只是… stackoverflow.com 我希望苹果能尽快解决此问题,因为现在Playgrounds与使用Swift进行iOS开发毫不费力地相反,并且通过此修复,您可以在进行更改后松开热装。 😞 参加可可豆聚会 上周三,我去了Cocoaheads在柏林的Sauce Labs办公室聚会。 这是我第一个iOS开发人员见面,所以我感到非常兴奋。 地点是美丽的,人民很好和善良。 拿了一片比萨饼和一瓶啤酒后,我准备好进行演讲了。 丹尼尔·保卢斯(Daniel Paulus)谈论了反向工程iOS内部的实用方法,增强现实:Berta Devant的《从设计到开发》,以及鲍勃·戈德温(Bob Godwin)的Swift关联类型设计模式。 我必须承认,第一个和最后一个谈话在我目前的水平上已经取得了很大进步,但是所有主题仍然非常有趣,我想稍后再回到此以进一步了解它。 每个月都有另一个聚会,我期待下一个聚会。 如果您有兴趣,请访问https://www.meetup.com/de-DE/Cocoaheads-Berlin/。 构建我的第一个应用 为了练习现在正在学习的内容,我想开始我的第一个项目。 我完成了一些小型指导项目,产生了示例应用程序,但是这次我想启动自己的应用程序。 这个学期我要参加关于计算(或理论计算机科学)基础知识的讲座。 对我来说,绕开像自动机理论这样的超级抽象主题是非常具有挑战性的。 此外,还有许多符号和定义很难记住。 对每个主题都有一些易于理解的总结,以及符号和定义的集合,将是很好的。 我的目标是为此目的创建一个简单的应用程序,并将其分发到App Store中,以帮助其他学生和我自己。 在德语中,我们将该主题称为“信息基础理论”,它将转化为理论计算机科学。 在uni,我们将其缩写为“ TheGI”。 因此,名称将为“ TheGI-App”(直到我会发现更好的东西)。 本周目标 制作TheGI […]