Tag: Swift 4

Swift 4 ~~高阶函数-过滤,映射,归约和排序

您可能已经听说过Swift中的高阶函数 。 简单来说,高阶函数是开发人员友好的代码段,可在几行内完成复杂的计算。 很快我们有了Filter() , Map() , Reduce()和Sorted() HOF。 所有这些都有其自身的优点,并且在我们的代码中易于使用。 让我通过Swift4中的一些有趣的示例向您展示如何使用它们。 1.过滤器(_ 🙂 Filter方法将检查条件,如果条件满足,它将返回一个对象。 您可以将filter(_ 🙂与String,Array,Dictionary,Set等一起使用。 让我们在Set上看看如何使用它。 我有一组名称,我需要选择只有5个字符的名称。 那我该怎么办呢? //名称集 let nameSet:Set = [“ trivan”,“ mary”,“ larns”,“ tria”] //结果集 var resultSet:Set = [] //遍历nameSet中的每个元素 nameSet.forEach {(元素)在 如果element.count == 5 { resultSet.insert(element) } } print(resultSet) 如何使用HOF 过滤器(_ 🙂完成此操作? 让我用过滤器(_ 🙂向您展示上述要求的代码 let nameSet:Set = [“ trivan”,“ mary”,“ […]

心情不好的雨燕4,1

与往常一样,当新版本的Swift出现时,我会通读手册并提出问题供审核。 因此,这里我们使用Strings。 如您所知,字符串再一次是集合类型,因此不再是.characters,对此我们可能都非常感谢。 如何创建多行字符串? 使用三引号 让x =“”“ 他说她说 然后更多 然后更多 “” 注意,绿色的新兵,是确定缩进从何处开始的BOTTOM三重引号。 您可以添加缩进,也可以添加\以将一行连接在一起。 从字符串中获取子字符串时,它是什么类型? 串? 不,温柔的灵魂,不是弦乐。 它是SubString。 字符串和子字符串共享什么协议? 他们共享StringProtocol。 哦! 这就是为什么字符串操作类型如此频繁地将StringProtocol类型作为输入吗? 就像你说的那样。 你比你看起来聪明。 很高兴知道默认情况下复制可确保始终在后台复制作为真正的14克拉值类型的字符串。 你看到我在那里做什么了吗? 并非总是在后台复制它。 它通常通过引用传递,并且仅在您要使String突变时才执行复制。 由于这个邪恶的小把戏,您将获得更多的性能提升。 如果可以的话,请稍作努力。 一点点ol’-razzle-dazzle三卡牌游戏。 为什么它是邪恶的? 这不是真的邪恶。 哇,您可以在字符串后附加一个字符! 像您一样使用+进行串联? 不,那太明显了。 您必须使用 aString.append(“C”) 方法。 什么是字符串互通? 我认为您的意思是字符串插值。 这只是意味着使用变量将一个字符串插入另一个字符串。 就像使用C和其他语言一样。 您可以通过字符数组创建字符串吗? 你肯定可以,甜蜜的脸颊。 刚把那个吸盘扔进弦里,嘿嘿。 你在骚扰我吗? 你要我吗 您想让我发出触发警告,以免引起皮疹或其他事情吗? 你的举止很差。 我做。 我度过漫长的冬夜,为他们而悲伤。 什么是扩展字素簇? 好吧,你成功地做到了。 它是一个或多个unicode字符的序列,导致一个字符,即一个和一个唯一的人类可读字符。 那么,是否要遍历每个Unicode标量来计算字符串中的人类可读字符? […]

Swift 4 ile VideoSıkıştırma

Herkese merhabaarkadaşlar。 Bildiğinizüzerediğerdillerdeolduğugibi Swift’e de ait internette pek fazlaTürkçekaynakbulamamaktayız。 您可以在olmakadınakendi projemdekullanmışolduğumvegerçektenişeyarayacağınıdüşündüğümbir konuyla seriyebaşlamışbulundum。 Başlıktandaanlaşılacağıüzerebugün视频sıkıştırmadanbahsedeceğiz。 您可以在磁盘上找到磁盘,然后在磁盘上添加文件。yaptıysanızkeinlikleihtiyaçduyacaksınız。 Ayrıcabildiğinizgibiyüksekboyuttakivideolarıuzunsürelerde上传了etme durumudasözkonusu。 Birdakikalıkbir videonun ortalama 100 MBdolaylarındaolduğunudüşünürsekkullanıcılarınızsizikötüanmasımuhtemelenkaçınılmazolacaktır。 视频sıkıştırmaylailgilibirçok算法mevcut fakat buyazıdaAVFoundation’ıniçindebulunan AVAssetExportSession kullanarak buişlemigerçekleştirececeiz。 Sıkıştırmadanziyadeküçültmedediyebiliriz :)。 Buişlemibir fonksiyoniçerisindegerçekleştireceğiz。 FonksiyonagöndereceğimizinputURL(Videomuzunbulunduğukonumun adresi。路径olaraktatanımlanabilir。)ve outputURL (Sıkışmasonucunda almakistediğimizkonumun adresi。)olacak。 Fonksiyonumuzuoluşturmayabaşlayabiliriz。 func compressVideo(inputURL:URL,outputURL:URL,handler:@escaping(_ exportSession:AVAssetExportSession?)->无效){ } Yukarıdakigibi compressVideoadındabir fonksiyonoluşturduk。 3 adetdeğervar输入ve输出URL’leri ve bir adet handlerimiz。 否否输出否否是kullandığımızdanyukarıdabahsetmiştik。 handlerimiziniçindebir @转义ekintanımladık。 […]

在Swift中为函数创建完成回调

如果您问我:什么是“完成”? 我会回答这个问题:在我看来,完成就像每顿饭中的甜点,它们不是必不可少的,但它们仅在您完成主菜时才使用。 请记住,补全仅在函数的末尾运行。 我们看到完成的最常见的地方是下面的两个坏男孩。 dismiss(动画:Bool,完成:(()-> Void)?)present(viewControllerToPresent:UIViewController,动画:Bool,完成:(()-> Void)?) 它们非常方便,例如,我有一个类型为Boolean的变量,并且我想在其中完成一个函数的调用时将其状态从true更改为false,然后可以将下面的代码放到完成块中,将在函数末尾被调用,因此我的变量将为false。 变量=!变量 实际上,它并不像看起来那样难。 当您点击键盘上的“ enter”键时,我们将创建相同的效果,Xcode会自动为您打开补全框。 为了最大程度地减少使用自己的功能时的工作量。 1.创建一个函数: 功能展示(didFinish:Bool){ 打印(didFinish) } 2.现在,将完成块添加到函数中: 不要忘记问号,因为餐后甜点不是必不可少的,所以完成块也是如此,在某些情况下,不需要完成块。 函数演示(didFinish:Bool,完成:(()-> Void)?= nil){ 打印(didFinish) } 3.实施: 我们必须确保完成块中有内容,因此请先检查是否为nil,如果为nil,则从此处返回该函数,否则请继续。 函数演示(didFinish:Bool,完成:(()-> Void)?= nil){ 打印(didFinish) 后卫完成!=除此以外{ 返回 } 完成!() } 让我们使用它 var demo = true 示范(didFinish:演示){ 演示=!演示 打印(演示) } //输出: //正确 //错误 附言:如果您在函数中使用动画,则将完成块放在后面将无法解决问题,您必须为完成添加一个延迟(恰好是动画要花费的时间)。就像是: DispatchQueue.main.asyncAfter(截止日期:.now()+ YourAnimationTime){ 完成!() } )。 感谢您的阅读,如果有什么我忘了提的话,请随时在评论部分询问我。 最后〜编码愉快〜🙂

Swift中的Hashable OptionSet

2018年8月29日·2分钟阅读 这篇文章解释了如何在Swift中创建一个OptionSet,该OptionSet还实现了Hashable协议。 这样,它可以在字典中使用。 即使它非常简单,我也无法在线找到一个文档化的示例,因此我认为我可以将其组合在一起。 我最近一直在使用Apple的SpriteKit开发一款游戏,并达到了实现和跟踪游戏内成就的地步。 reddit上的一个用户建议使用OptionSet来存储已解锁的成就,并使用Dictionary作为各种“成就百科全书” ,这真是一个不错的建议! 为了使这项工作可行,OptionSet还必须实现Hashable协议。 为什么对我的用例有意义: OptionSet使按位操作相对不费力,因此避免了头痛 我没有计划大量的成就(限制是整数的位数) 在UserDefaults中存储整数(OptionSet的rawValue)非常容易,而且存储效率高。 需要hashValue整数作为唯一(理想情况下)分析哈希内容的方式 ==函数比较散列。 此实现使用OptionSet的rawValue作为唯一指示符。 由于hashValue符合rawValue ,因此它在==函数中使用。 这样,我们可以将责任整合到hashValue中 。 但是,您也可以返回: 返回lhs.rawValue == rhs.rawValue 乔伊斯·马托斯(Joyce Matos)对Hashable的分解 最初在 nathanwillson.com上 发布 。

Swift框架-章:1。 开发一个Swift框架

Swift框架很棒! 在Daniel Isaac的西班牙语中找到本章。 WORE —到处运行一次编写,现在与Java一起用于Swift。 实际上,Swift已成为一种流行的编程语言,并且每天都在发展。 开发Swift框架具有以下优点。 隐藏您的代码实现。 由于.framework文件已经编译,因此将减少重新编译并节省开发时间。 这就是Apple使用的工具,例如:UIKit.framework。 那么,您在寻找什么?让我们现在开始开发自己的Swift框架。 使用的工具:XCode 9.3 +,Swift 4.1+ 步骤1:-安装框架项目 创建新的XCode项目。 单击可可触摸框架 为您的项目命名,我们使用的AlamoWater声音类似于 Alamofire 。 (请务必选择语言-Swift) 单击目标内的AlamoWater文件夹,然后按⌘+N。 选择文件名AlamoWater和以下子类:NSObject 步骤2:-编写一些代码 在AlameWater.swift中添加以下代码。 注意:-确保您的类和方法已打开 。 并添加运行脚本 。 在Ch:1-GitHub上获取完整的SourceCode。

在Xcode 10和Swift 4中将核心数据添加到现有项目

只需几个步骤,即可将Core Data功能添加到现有项目中。 核心数据是Apple提供的框架,用于管理应用程序中的模型层。 在谈论MVC(模型,视图,控制器)体系结构时,核心数据本质上是模型部分。 如果您正在用Xcode开发一个iOS应用程序,并且您决定要使用Core Data,但在项目中未启用它,请不要担心! 可以添加一些简单的步骤,我们将在本文中介绍这些步骤。 该技术还可以使您轻松地将核心数据添加到其他应用程序项目类型,例如基于页面的应用程序或选项卡式应用程序。 我们将执行以下步骤,将Core Data放入我们现有的应用中: 创建一个启用了核心数据的新Single View应用程序-完成后我们可以删除此项目 将项目的AppDelegate.swift的相关部分复制到我们现有项目的AppDelegate.swift 在我们现有的项目中创建一个新的核心数据数据模型并适当命名 确保正确引用了数据模型 测试! 因此,在打开现有项目的情况下,在Xcode中创建一个新项目( ⇧⌘N ),然后选择一个Single View App,您可以随意调用它,因为我们将在完成后将其删除。 您将在项目选项屏幕上看到“使用核心数据”复选框,确保已选中它。 现在,我们需要在这个新项目中打开AppDelegate.swift文件,并向下滚动到文件末尾,在这里我们需要将所有内容从applicationWillTerminate()复制到文件末尾: func applicationWillTerminate( _ application:UIApplication){ //在应用程序即将终止时调用。 如果合适,保存数据。 另请参阅applicationDidEnterBackground:。 //在应用程序终止之前将更改保存在应用程序的托管对象上下文中。 自我 .saveContext() } // MARK:-核心数据栈 懒惰的 varpersistentContainer:NSPersistentContainer = { / * 应用程序的持久性容器。 这个实现 创建并返回一个容器,并已为 应用到它。 该属性是可选的,因为存在合法的 可能导致存储创建失败的错误条件。 * / 让容器= NSPersistentContainer(名称:“您的数据模型文件”) container.loadPersistentStores(completionHandler:{(storeDescription,error) 在 如果 […]

WWDC 2018 — Swift 4.2和“随机”更改

在WWDC 2018中,Swift 4.2引入了新方法来生成和访问集合中的随机值。 通常,应用程序开发人员会在构建游戏或创建测试数据时执行此操作。 让我们看一下访问随机项目的旧方法和新方法。 随机访问和旧版API 在一开始,Swift依靠旧的系统级C库生成随机数。 在Apple设备上,这是通过Darwin函数arc4random_uniform 。 尽管它确实可以满足您的要求,但是除了UInt32之外,它还需要对类型进行大量工作。 例如,如果您需要构建一个浮点数,则需要: let minimum = -7.9 let maximum = 12.8 let doubleValue = (Double(arc4random_uniform(UInt32.max)) / Double(UInt32.max)) * (maximum – minimum) + minimum 这导致一些开发人员构建软件包来简化此过程。 RandomKit和简化随机生成 RandomKit是一个库,在简化该库方面做得很好。 每个简单类型都有一个静态函数,用于根据提供的生成器的类型生成值: let value = Int.random(using: &Xoroshiro.default) 生成器实现RandomGenerator协议,该协议提供生成值所需的实现。 RandomKit还提供以下方法: 从数组中选择随机值 改组数组 生成其他类型,例如日期,(NS / UI)颜色,CGPoint等 Swift 4.2和WWDC 2018 提案SE-0202似乎可以解决许多不一致问题,这些不一致问题是由于跨操作系统(Linux与macOS)的随机生成和访问以及简化API所引起的。 它似乎也正在采取类似于RandomKit的方法。 例如,要生成某个范围内的随机Double,所需要做的就是: Double.random(in: -7.9…12.8) […]

避免RxSwift内存泄漏

我最近对RxSwift的优雅充满热情。 我仍在学习使用RxSwift的越来越好的方法,在这篇简短的文章中,我将分享一些我所学到的避免内存泄漏的知识。 我希望这些指针对那些可能遇到相同问题并寻求解决方案的人有用。 首先,有一点背景。 在我们的项目中,我们使用模型视图呈现器(MVP)架构,其中呈现器具有关于UI如何响应输入以及处理与模型对象的所有交互的所有逻辑。 演示者与视图和模型交互,但是模型和视图不直接交互。 注意,视图≠视图控制器。 在我们的项目中,视图是由视图控制器实现的协议,用于向演示者公开特定的接口。 因此,演示者必须同时引用视图和演示者。 该视图对演示者有很强的参考力,因此可以在加载视图后向演示者注册自己,以便在视图卸载后可以释放演示者。 因此,演示者必须对该视图有较弱的引用,以避免保留周期。 我们在项目中创建的每个视图都将在viewDidLoad()末尾调用其演示者进行注册。 演示者可以在此订阅UI中的可观察对象,并可以绑定到UI控件。 这是一个视图控制器向其演示者注册的示例: 演示者的registerView()方法将以一种非常声明性的方式定义所有UI逻辑。 这是一个部分示例: 难题#1-函数参数 在这里,您可以看到演示者如何要求模型使用URL提取图像,以及Observable使用活页夹将Observable绑定到视图中的UIImageView 。 但是,示例代码已经存在问题。 在bind(to: createPostView.posterImageBinder) , createPostView参数是对该视图的强引用。 由于该视图对演示者有很强的参考作用,因此从一开始就存在一个保留周期。 视图,演示者和模型将在视图卸载后保留在内存中。 更糟糕的是,下次加载该视图时,将创建并保留这三个视图的另一个副本。 但是,有一个简单而优雅的解决方案,即使用局部变量作为在弱变量中捕获视图的方法。 现在,对该视图的引用很少,并且没有保留周期。 难题#2-实例变量 这是有时会出现的另一种有问题的模式: 在上面的代码中有两个问题。 让我们解决第一个问题。 在flatMapLatest { self.createPostModel.createPost(text: $0, image: $1) }行中,没有显式self不会编译实例变量,这将与presenter和闭包创建一个保留周期。 我们可以使用另一个局部常量来解决此问题,以获取模型参考而不引用self。 看起来像这样: 难题#3-函数参考 上面的代码中仍然存在一个严重的问题,它将在视图和演示者之间创建一个保留周期。 你能发现吗? 它在subscribe(onNext: view.pop) 。 这是微妙的。 事实证明,如果在Swift中使用函数引用,则编译器会创建一个对要在其上执行函数的实例的强引用。 因此,即使view变量本身被声明为weak,使用view.pop仍会创建对view的强引用。 有趣的是,使用view.pop()将具有弱引用。 也许将来的Swift版本会解决这个问题。 在撰写本文时,Swift 4.2在使用函数引用语法时正在捕获强大的引用。 […]

Swift中的泛型函数

泛型是Swift最强大的功能之一,许多Swift标准库都是使用泛型代码构建的。 Swift 4语言提供“通用”功能来编写灵活且可重用的函数和类型。 泛型用于避免重复并提供抽象。 现在让我们看看快速语言中泛型函数的用法以及如何使用它。 例如,考虑使用以下程序交换值。 如果我们看上面的程序,该函数仅接受Int值。 因此,如果我们要编写用于接受“ String”或“ Double”值的函数,则必须编写两个类似的函数,用“ String”或“ Double”替换“ Int”。 因此,如果我们要编写一个接受任何类型的函数(无论是Int , Double还是String) ,该怎么办。 ? 为此,我们需要编写通用函数。 如何编写泛型函数? Swift 4提供作为通用类型参数名称 func swapTwoValues(_ a: inout T, _ b: inout T) { let temporaryA = a a = b b = temporaryA } swapTwoValues(_:_:)函数的主体与swapTwoInts(_:_:)函数的主体相同。 但是, swapTwoValues(_:_:)的第一行与swapTwoValues(_:_:)略有不同。 以下是第一行的比较: func swapTwoInts(_ a: inout Int, _ b: inout […]