Tag: 协议

细胞协议铸造

多单元转换可能是使用大型视图控制器的最大原因。 我已经在互联网上进行了广泛的搜索,发现的并不是一个庞大的视图控制器。 我敢肯定我们都看过这样的东西👇👇👇👇👇 不,我不会谈论MVVM。 我们可以做得更好! 第一个解决方案将是Swift 4.2,然后是Swift 4.1 30号线 UserTableViewControler符合CellDelegate 可能不是分配委托的最佳方法。 但这是避免多细胞铸造的关键。 您还可以避免对多个单元格进行检查,从而使tapped()成为可选选项,但是我很累,因此我将让您弄清楚这一点。 1号线 参数类型T提供了更大的灵活性,并避免了针对不同数据类型的多种协议。 由于CaseIterable在swift 4.1上不可用,因此枚举的RawValue类型为Int,标识符变量返回单元格标识符。 而已! 其他一切都保持不变。 在GitHub上下载完整的解决方案。 Swift 4.2 https://github.com/ErickApps/ProtocolCellsSwift4.2 Swift 4.1 https://github.com/ErickApps/ProtocolCellSwift4.1 确保跟随这些家伙 保罗·哈德森 推特:@seanallen_dev 推特:@buildthatapp 雷·温德利希 结论 不是MVVM解决方案🤪 减少键入和调试。 不再施力👇👇👇👇👇👇 批评总是受到欢迎。 在Twitter上让我知道:@ pitjits u

类型擦除— Apagando tipos!?

向前,向后,向后,向前,向后,向后推荐方案的协议: https://www.raywenderlich.com/148448/introducing-protocol-oriented-programming https://developer.apple.com/videos/play/wwdc2015/408/ Mas por queiríamosquerer“ apagar” um tipo? 您可以在法律上迅速获得Swiftéuma linguagem fortemente tipada的权利 。 可以通过entãoiríamosquerer“ apagar” um tipo吗? 参赞者,vamos primeiro参评者,que queremos solucionar com essaestratégia。 Swift和jáse aventurou pelas suas的通用协议具有 maisavançadas,dave ter tentado usar与“ famosos” 相关类型 (tipos associados)。 注意 :在Swift 2.2中引入了相关类型,而在“ typealias”时代之前,它已被使用 Em resumo,um 关联类型 ,通用协议的“ nada maisédo que ”,“ propusade”的服务对象,parâmetro, “ retorno demétodos”等的服务。Imagine-o como uma caixa […]

Swift:委托和协议

与Swift在一起待了将近10天,即将到来的项目。 一切工作都很好,直到出现了“委托和协议”之类的内容,才真正使我难受。 这就是为什么此注释旨在揭示后续回调的基本原理的原因。 由于本文仅供个人使用和注意,因此本文内容非常密集,请随时向我询问详细说明。 1.什么是委托和协议? 简而言之,这是iOS应用程序开发中的一种设计模式,用于处理从一个视图控制器到另一个视图控制器的数据传递。 期。 2.为什么我们在地球上需要委托和协议? 这是一个非常大的问题。 让我们首先回顾一下在Swift中传递数据的传统方法,以掌握全局。 为第一个视图控制器和第二个视图控制器设置两个设置: 第一视图控制器: // ViewController.swift // Segues // //由VuNguyen创建于2018/11/17。 //版权所有©2018 VuNguyen。 版权所有。 // 导入UIKit 类ViewController :UIViewController {var textFromSecondView:字符串? @IBOutlet弱var firstLabel:UILabel! @IBOutlet var textField:UITextView! 覆盖func viewDidLoad(){ super.viewDidLoad() //加载视图后进行其他任何设置,通常是从笔尖进行。 firstLabel.text = textFromSecondView } @IBAction func sendDataForward(_ sender:UIButton){ performSegue(withIdentifier:“ goToSecondScreen”,发送者:self) } 覆盖func prepare(用于segue:UIStoryboardSegue,发送者:Any?){如果segue.identifier ==“ goToSecondScreen” { 让destinationVC = segue.destination作为! […]

协议-Swift的力量

更新于2019年2月24日,格林尼治标准时间上午4:51 5:30+ 先决条件—任何Swifty iDev均可初学者或专家阅读。 通过从头到尾阅读本系列文章,初学者将获得知识,专家将增强其知识。 我们都知道Apple的UIKit,MapKit和所有其他框架都是在委托模式的基础上开发的。 大多数iDev都知道协议是用于委托人和数据源在视图,视图控制器或自定义类之间传递和请求数据的,但是该协议的真正功能是类型转换 ,AnyObject是迅速实现的协议,用于存储任何类型的对象。 类型转换是将变量或值的数据类型从一种类型转换为另一种类型的过程。 我还有一个问题,如果上面是类型转换,那么协议在这里的作用是什么? 当然,经过几个动作,我会给这个问题一个答案,敬请期待。 让我们首先介绍基本概念。 以上只是原始类型转换的一个简单示例。 原始类型转换是由Int,Float,Double等编程语言提供的原始数据类型之间的类型转换。 另一种类型转换是类级别的类型转换,有时称为自定义类型转换。 类,结构,枚举被视为可以由像您这样的开发人员创建的自定义类型,自定义类型转换在继承中起关键作用。 — — — — — — — — — — — — — — 该类的每个实例都有#n个类类型 — — — — — — — — — — — — — — 如果A类不是任何类的子类,则#n将为A类 [例如(A类)— A没有任何超类] — — — — — — — […]

协议之外

考虑一下协议。 我们在应用程序中广泛使用它们来委派操作,支持多重继承概念并在引用和值类型上创建复合功能。 更进一步,我们可以通过使类和类型定义符合协议来扩展它们。 我们可以定义协议类型变量并使我们的类型更灵活(不包括关联类型和自我需求协议)。 每个(不透明的)容器在内存中都有3个部分: 三个存储字的长度缓冲区,用于保存Value :如果值的大小大于3个字,则将其存储在堆中,并且地址保存在此处。 MemoryLayout.size(ofValue:alice)// 32字节 //因此将其存储在堆中,并将其地址保存在值缓冲区中 一个记忆词表示“ 元数据 ” 每种协议类型都有一个存储字,用于存储“ 协议见证表 ” 。 如果您的变量由N个不同的协议组成,则将其计算为N个存储字。 对于* protocol的声明*中的每个方法,都有一个指向其符合类型的实现的指针。 因此,当您在协议扩展中定义一个方法时,该方法将不会出现在见证表中,并且在您的变量上使用该方法时,它会被静态分派,并返回其默认实现,如上面的示例。 如果您想要重写的实现,则只需将其添加到协议声明部分,即可按预期工作😊

iOS协议:可哈希

在上一篇文章中,我们讨论了相等和可比较的协议,我们将研究另一个更快的协议,即Hashable。 Hashable是一种协议,它提供了使用自定义类的对象作为Dictionary或set中的键的功能,按照APPLE定义的可哈希值: 提供整数哈希值的类型。 许多内置类型提供哈希值,或者我会说它们符合哈希协议,包括字符串,整数,浮点数和布尔值,甚至是集合。 注意: 当您定义一个没有关联值的枚举时,它会 自动 获得可 Hashable 一致性。 如果您使用Hashable协议使一个类符合并且该类的实例相等,即a == b,则a.hashvalue == b.hashvalue也将适用,但相反情况并非如此。 按照苹果: 哈希值不能保证在程序的不同执行中相等。 不要保存哈希值以供将来执行。 哈希协议是从等同协议继承而来的,因此您需要同时遵守这两个协议。 让我们借助示例来了解事物:- 我们将使用rollNumber创建一个名为“ Student”的快捷类。 现在我们需要添加可哈希的 弹出有关可哈希和等值一致性的错误。我们将重写“ ==”运算符以实现等值一致性,并提供hashValue,hashValue应该是计算属性,但在示例中作为实验,我们将其用作存储属性。 班级学生:适用于{ var hashValue:Int = 0静态函数==(lhs:学生,rhs:学生)-> Bool {如果lhs.rollNumber == rhs.rollNumber {返回true}返回false} let rollNumber:Int init(rollnumber:Int = 0 ){self.rollNumber = rollnumber}} 现在,如果我们创建此Student类的实例并将其用作哈希值,则可以查看结果。 让lovekesh:Student = Student(rollnumber:1)var studentInfo:Dictionary =字典() 在这里,我们创建了一个名为hashpValue值为0,rollnumber为1的Student实例“ Lovekesh”,并以Student为键声明了StudentInfo字典。 studentInfo [lovekesh] =“第十标准” 打印(studentInfo […]

斯威夫特的数字协议

我在新加坡iOS Conf的Jesse Squires演讲中,他讨论了Swift的数字类型和协议。 这让我想起了SE-0104(面向协议的整数),现在该实现是在Swift 4中进行的,认为现在是仔细研究的好时机。 让我们从每个人喜欢的整数类型Int的协议层次结构开始: 与标准库中的大多数类型一样, Int符合很多协议! 从头到尾, Numeric是基本协议之一。 所有不同大小的整数类型( UInt , Int8等)以及浮点类型( Float , Double等)都符合Numeric 。 数值,从0x00开始 您可以在Integers.swift.gyb中遵循标准库源代码,尽管照常,所有相关代码都将在下面内联。 这是开始的协议声明: public protocol Numeric : Equatable, ExpressibleByIntegerLiteral { 这里有另外两个符合性: Equatable增加了对==运算符的支持。 ExpressibleByIntegerLiteral允许使用let a: Int = 42这样的代码let a: Int = 42其中42是上述的“整数文字”。 这意味着所有数字类型都可以使用整数文字进行初始化,但不能使用浮点文字进行初始化。 这段代码可以: let someFloat: Float = 42 // ✅ 但这不行: let someInt: Int = 4.2 // […]

快速,更优雅的代码:OptionSet

您是否想知道如何在Swift中处理Bitmasks? 您是否听说过 OptionSet 并且想了解更多? 好吧,这是给你的! 什么是OptionSet? 基本上,OptionSet是一种符合它的协议,使您能够进行位屏蔽。 它是位集的表示,每个位都代表一个选项。 听起来不清楚? 让我们编写代码: 如何实现OptionSet? 这是一个符合OptionSet的Structure的基本实现: struct MyStruct:OptionSet { let rawValue:Int静态let firstOption = MyStruct(rawValue:1 << 0) 静态让secondOption = MyStruct(rawValue:1 << 1) 静态让thirdOption = MyStruct(rawValue:1 << 2) } 让我们解释一下上面的代码中发生了什么: 符合OptionSet要求声明rawValue ,它不必是Int类型,而是任何类型的FixedWidthInteger例如Int8或Int16 。 接下来,您需要静态地声明所需的选项,然后猜猜是什么? 这就是创建选项集所要做的全部! 好吧,我想假设您仍然对自己声明选项有些困惑,您可能会想到“为什么它必须是静态的? 什么是<<东西?” 补充工具栏注意 :如果您不那么了解,那么在直接进入OptionSet选项声明之前,我建议您熟悉“一对一”的世界。 了解十进制值的二进制表示形式将使理解和实现OptionSet选项更加容易。 这是一篇很酷的文章:位,字节,用二进​​制构建。 从逻辑上讲,应该将选项声明为static ,因为您可以直接访问它,而无需从一致的结构(在我们的示例中为MyStruct )实例化-稍后我们将看到。 接下来,应将选项声明为一致结构的实例(在我们的示例中为MyStruct),并为其分配所需的“二进制计数” rawValue,这就是使用<< 左移运算符的目的。 尽管我建议您查看按位运算符的文档-按位左移和向右移位运算符,但我还是要简要介绍一下它的工作原理:它将所有数字向左移动,例如: 让一个= 0b0001 // […]

如何处理值类型的递归

在我们的应用程序中,当我们需要共享状态时,我们可以使用引用类型。 例如,视图,视图控制器和模型控制器需要是引用类型。 但是,我们应用的模型必须是值类型,以便我们可以传递本地副本。 否则,您可能会遇到更改模型状态的问题,并在应用程序的其他位置产生副作用。 因为您的模型类型也是传递最多的模型类型,所以当它们是引用类型时,可能会对内存管理产生更大的影响。 Swift的问题在于,由于存在内存管理问题,它不允许使用递归值类型。 值类型分配在堆栈上,而不分配在堆上。 它们的大小必须固定,因为操作系统需要知道将它们放入堆栈的大小。 将它们放在堆栈上之后,它们的大小将无法增长,因为其他数据将被置于它们之上。 如果结构包含自身,则系统无法计算其大小。 这就是为什么Swift不允许递归值类型,并且您不能编写这样的代码的原因: 结构TypeA { 让其他:TypeA } 或这个: 结构TypeA { 让其他:B型 } 结构B型{ 让其他:TypeA } 有两种解决此问题的方法: 集合提供足够的间接性以允许递归引用 只有一个参考时使用协议 假设我们有两个结构。 一个用于用户 ,一个用于博客 。 User结构具有一个属性,该属性包含该用户的所有已发布博客,该属性包含该用户的所有关注者,以及一个属性lastBlog(用于最近发布的博客)。 Blog结构具有此Blog作者的属性,类型为User 。 我们可以通过为其中一个用户创建协议来解决User结构的LatestBlog属性和Blog结构的author属性的递归引用问题。 在我们的Blog结构中。 属性博客和User结构的关注者的收集类型提供了足够的间接方式来规避此问题: struct用户{ 命名:字符串 var博客:[Blog] var个关注者:[User] var LatestBlog:BlogType? } 协议 BlogType {} struct Blog:BlogType { 让日期:日期 让内容:字符串 让作者:用户 }

iOS初学者代表

iOS开发的大多数初学者在理解委托人时都有问题。 苹果公司说,委托是一个对象,当另一个对象遇到程序中的事件时,该对象代表另一个对象或与另一个对象协同工作。 为简化起见,委托是一个对象,它允许对象A和对象B使用函数或变量相互通信。 代表由程序中的事件触发(例如,按下按钮)。 让我在一个将数据从自定义视图传输到视图控制器的简单示例中为您解释一下。 让我们从创建一个新的Xcode项目开始; 所以打开Xcode,选择Create a new Xcode project 选择Single View App,然后按Next。 在产品名称字段中,输入DelegateExample,然后按下一步->创建。 好的,现在我们已经建立了一个项目,可以开始了。 现在我们需要创建一个代表对象B的自定义视图。我们的对象A将是View Controller,并且已经由Xcode创建。 因此,要创建自定义视图,请导航到Xcode窗口左侧的项目树,右键单击Delegate Example文件夹,然后单击“新建文件”。 选择Swift文件,然后单击Next。 在另存为字段中输入CustomView,然后按创建 现在,我们将为CustomView创建一个.xib文件。 为此,再次右键单击Delegate Example文件夹,然后选择New File…,但是这次选择View并按Next。 再次将文件命名为CustomView,然后单击“创建”。 现在,您应该在项目树中看到一个CustomView.xib文件,并且应该有一个类似于以下内容的屏幕。 好的,进入代码。 打开您的CustomView.swift文件并为我们的自定义视图创建一个类。 为此,只需在文件中键入此代码即可。 进口基金会 导入UIKit 类CustomView:UIView { } 现在,我们需要在.xib文件的视图中添加一个类。 导航到CustomView.xib,然后在“检查器”选项卡的顶部选择“身份检查器”。在“类”字段中,输入CustomView,然后按Enter。 现在,在屏幕上的某处添加一个按钮和文本字段。 我将像这样将它们添加到屏幕的中央。 现在回到代码,我们需要为文本字段和按钮创建出口。 为此,请将此代码添加到CustomView类。 @IBOutlet弱var textField:UITextField! @IBOutlet弱变量按钮:UIButton! 现在,将插座与.xib文件中视图内部的文本字段和按钮相连。 为此,请再次导航到“检查器”,然后选择“连接”检查器。 您将看到我们刚刚创建的两个出口。 要连接它们,只需在插座名称旁边的圆圈上按文本框和按钮,然后将它们拖放到视图中的文本框和按钮即可。 现在,让我们以相同的方式在View Controller中添加标签。 转到ViewController.swift文件,并将此代码添加到ViewController类中。 @IBOutlet弱var标签:UILabel! 转到Main.storyboard,向ViewController添加标签和按钮,然后使用检查器连接标签出口。 太好了,现在我们已经设置了对象A和对象B。我们的对象A将是ViewController,而我们的对象B将是CustomView。 […]