Objective C属性,Objective-C中最困难的部分。 很多时候,即使是开发人员,甚至是StackOverflow,都让您在何时需要使用哪个属性时陷入困境。 最终,随着ARC(自动引用计数)出现在市场上的岁月,iOS中的内存管理得到了改进,在该市场中,我们无需为对象释放后定义的所有对象进行dealloc和deinit定义。 ARC版本的内存管理的发布使iOS中的开发变得更加容易,并且内存泄漏等情况会自动得到多次处理。 我们将在这里讨论的主要目标C属性是: 强:强是保留的新形式。 到iOS 4为止,我们一直使用retain代替strong 。 Strong仅定义对象的所有权。 对象的生命周期将一直保留,直到所有者本身未取消分配对象为止。 我们通常对对象的父级使用strong ,即在UI Elements的情况下,对UIViewController使用strong 。 保留:保留还拥有object属性。 在一般情况下,当我们要为同一对象使用新的设置器时,如果要删除先前的值,则使用保留 。 弱:弱只是一个指针,仅在对象由某个强大属性拥有时才起作用。 我们通常使用弱以避免保留周期。 保留周期仅表示如果A强烈指向B,B强烈指向C,并且在任何情况下C似乎也强烈指向A,那么它将在所有A,B,C属性之间产生死锁。 为了避免保留周期,我们通常使任一过渡都变弱,而不是强过渡。 弱属性通常与IBOutlet,Delegates和其他Objective-C参考一起使用。 分配:分配是弱属性的旧版本。 到iOS 4为止,我们一直使用分配代替弱属性。 Assign主要用于基本数据类型,例如int,float等。 原子:在线程安全的情况下,原子属性是默认属性,但可以用nonatomic覆盖。 原子属性定义属性是线程安全的,并且将始终返回真实值。 垃圾值的可能性是最小的。 由于它是线程安全属性,因此比其竞争对手nonatomic花费更多的时间执行。 NonAtomic:NonAtomic属性不是线程安全的,不能保证结果真实,但始终会给出结果。 简单的情况就可以理解,如果A将B设置为“ Srijan”,而C将B设置为“ Kumar”,则D可能会想要D获得B的值,这可能会产生类似“ Srimar”或“ janKum”,但非原子总是给出结果。 因为它不是线程安全的属性,所以它比atomic快。 对于几乎是类的对象,我们盲目使用非原子。 ReadOnly:顾名思义,readonly属性增强了该属性的接口,即其他对象只能读取该属性,而不能设置该属性的值。 我们使用只读,不想让其他类设置属性的值。 读写:这也是默认行为。 一旦你合成了一个属性,它就可以对该属性进行获取和设置。我们只需在实现模块中编写@synthesize即可 。
在Swift编程中,您可能已经看到一些带有“强”或“弱”引用的变量,例如: 事实证明,“强”,“弱”和“无主”是与内存管理相关的参考。 让我们进一步研究。 Swift和Objective-C具有管理应用程序内存的便捷方法: ARC (自动引用计数) 。 自2011年Apple在2011年WWDC上推出ARC以来,iOS开发人员就可以使用ARC。 在过去的日子里,程序员必须使用一种称为MMR(手动零售发行版)的内存管理方法,开发人员必须为每个创建的对象声明一个对象要保留在内存中,然后在不需要该对象时将其释放不再。 ARC做什么? 使用ARC,编译器会为类的每个实例分配一块内存。 这块内存保存与该实例的类型有关的信息以及与该实例关联的属性中存储的所有值 。 在实例化对象时,ARC会增加对该对象的引用数。 塔可类{ var order:命令? } 类Order { var taco:塔可? } var taco1 = TacoClass()// TacoClass的实例 var taco2 = taco1 // TacoClass的第二个实例 //在这里,我们实例化一个TacoClass并创建另一个引用。 //内存现在可以识别2个TacoClass 实例 。 随着时间的流逝,删除引用后,计数将减少(请参见下文)。 为避免崩溃, 只要 一个活动引用仍然存在,ARC就不会取消分配实例。 一旦引用计数达到零 ,ARC就会从内存中取消分配实例。 ARC如何做到这一点呢? Apple文档说: 为做到这一点,每当您将 类实例 分配给 属性,常量或变量时,该属性,常量或变量都会 强烈引用 该实例。 引用被称为“强引用”,因为它在该实例上保持坚挺,并且 只要该强引用仍然存在 , […]
在上一篇博客文章中,我们了解了iOS如何使用自动引用计数(ARC)作为其对象生存期管理系统。 在这篇文章中,我尝试指出ARC与垃圾回收或更具体地跟踪垃圾回收相比的一些显着差异(更精确的引用计数和跟踪是垃圾回收的两种不同实现。换句话说,ARC是由于跟踪垃圾收集是最常见的垃圾收集类型,因此通常术语“垃圾收集”是指跟踪垃圾收集。 ARC是使用对象所有权的编译器功能。 如果对象的引用计数为零(即不再拥有所有者),则ARC会从内存中释放对象,而不是在运行时在后台查找未使用的对象。 ARC在编译时会自动注入与Objective-C运行时等效的对象,以进行保留,释放(编译器在所有应有的位置插入保留和释放)。 我有整篇文章解释ARC的工作原理。 自动参考计数的优点 对象的销毁是实时且可预测的。 它具有对对象的确定性回收(当对对象的最后一个强引用消失时),而GC在“某个时候以后”释放对象。 如果没有长时间的收集周期就不能再引用它们,则将释放对象。 这样可以更快地释放对象。 这对于内存有限的系统(例如移动设备)很重要。 这定义了GC应用程序中可能存在的一类细微的错误,这些错误由于收集器不会在“错误的窗口中”触发而不会公开。 没有后台处理,这使得它在低功耗系统中再次变得更加高效。 如果活动对象集填满了大部分可用内存,那么跟踪垃圾回收周期就会触发得太多,这需要额外的空间来提高效率。 随着可用空间总量的减少,引用计数性能不会降低。 引用计数的渐近复杂度不取决于堆的总大小。 自动参考计数的缺点 无法收集保留周期。 保留周期即使无法访问,仍将参考计数保持在零以上 需要考虑多线程引用计数。 垃圾回收(GC)是一种自动内存管理尝试,用于回收垃圾或由程序不再使用的对象占用的内存。 在存在任何垃圾回收之前,您必须手动添加要保留和释放的调用(其他语言为“免费”或“销毁”)。 有几种实现垃圾回收的策略,最常见的两种是跟踪和引用计数。 .NET和Java平台使用跟踪垃圾收集。 垃圾收集在运行时起作用。 它检测未使用的对象,并在代码的任何部分不再使用它们时将其释放。 这发生的时间间隔不确定 (在经过一定时间后,或者在运行时看到可用内存变少时),因此不必在不再使用对象的确切时间释放对象。 垃圾收集的优势 GC可以清理整个对象图,包括保留周期。 这是垃圾回收相对于ARC的主要优势,您无需担心保留周期。 GC在后台发生,因此作为常规应用程序流程的一部分,内存管理工作量减少了。 垃圾回收的缺点 由于GC发生在后台,因此无法确定对象释放的确切时间范围。 当发生GC时,应用程序中的其他线程可能会暂时搁置。 ARC与GC 苹果的Objective-C邮件列表上的一个线程 垃圾收集简史 这个故事发表在中等规模最大的企业家精神出版物The Startup中,紧随其后的是295,232人。 订阅以在此处接收我们的热门新闻。
关于ARC的文章更多,其中有很多很好的例子。 我将保持简单。 该图中显示的示例演示了ARC的工作原理。 持有参考 简单来说,您创建的每个对象都有一个引用。 如果存在您可以访问并指向一个对象的变量或常量,则基本上意味着该变量将保留该引用。 参考类型 有3种参考类型: –强 –弱 –无人 请记住,ARC仅跟踪强引用。 那么ARC到底要跟踪什么? 好吧,我很高兴你问。 如上图所示,当其他变量持有对Car()的引用时,ARC会继续增加引用计数,而当变量设置为nil时,ARC会递减引用计数。 同样,当该引用计数为0时,ARC会为您删除分配的对象。 太好了,实际上,这是一个很棒的解决方案,我决定提供几行以纪念这个惊人的创作。 毒蛇 不,不是这个…… 如果您熟悉其他架构,例如MVC , MVP , MVVM,这将更容易理解。 体系结构的主要思想是将代码逻辑分离到不同的模块中,以便使其他开发人员更容易理解代码,并使代码更具可测试性。 选择使用哪种方法实际上取决于项目规模和团队协议。 涉及大型项目时, MV-X系列的体系结构存在一个常见问题。 而这个问题是大规模的视频监控器,演示者或视图模型。 这基本上意味着一个模块中的代码太多,以后可能会造成混乱。 这就是VIPER出现的原因之一。 VIPER通过进一步拆分代码来解决MV-X问题。 在5个主要模块中:视图,交互器,演示者,实体,路由器。
欢迎回到本教程的自动引用计数第二部分! 在第一部分中 ,您了解了ARC的一些基本概念,例如weak , Unowned 以及如何使用weak和unowned负责解决参考周期问题。 在最后一部分中,您将了解最后一种情况,在这两种情况下,两个properties都应具有值,并且初始化完成后,两个属性都不应该nil 。 此外,您还将学习如何克服Closures的强参考周期 。 让我们直接深入。 假设我们有一个Country和President类。 这些类中的每一个都将另一个类的实例存储为变量。 这意味着每个国家都应该有一个总统 ,每个总统都应该与一个国家联系在一起。 为了满足此要求而不会导致内存泄漏,您需要声明一个属性(在我们的示例中为Country类中的countryPresident )作为隐式展开的可选Property 。 这可以通过将感叹号放在其类型注释的末尾( President ! )来完成。 而另一方面,您需要将其声明为无主财产(在我们的country中为President阶级)。 国家 类别 { 让 countryName: 字符串 var countryPresident: 主席 ! 初始化 (countryName: String ,PresidentName: String ){ 自我 .countryName = countryName self .countryPresident = 总统 (presidentName:PresidentName,国家/地区: self ) 打印 (“国家正在初始化”) } deinit { […]
如果要开发高性能的iOS应用程序,则迟早必须考虑组件如何消耗可用的内存资源以及如何进行优化。 与内存管理有关的一个常见问题是保留周期问题。 但是在确切定义它之前,先看看iOS如何管理自己的内存? 苹果公司使用的自动内存管理方法称为ARC(自动引用计数)。 顾名思义,引用计数用于确定是否应释放内存块。 创建对象时,其引用计数以1开头。该引用计数在其生命周期中可以增加或减少。 最后,当引用计数达到0时,将从内存中释放对象。 下面是该生命周期的一个示例: 好了,现在是解释什么是强引用和弱引用的好时机。 在声明变量时,我们定义它是强还是弱。 变量默认为强。 我是安德烈。 一位年轻的巴西移动开发人员,喜欢与技术相关的一切。 如果您有任何疑问或建议,请随时与我联系。
并介绍自动释放池 ARC代表自动引用计数,Swift将其用于动态内存管理。 我正在遍历《 Swift编程语言(Swift 4) 》中的 “自动引用计数”一章,试图在遇到某些矛盾时涵盖所有角度。 至少那是我的第一个想法。 “自动引用计数”一章描述了强大的引用循环,展示了几种可能导致潜在引用的情况,最后,它针对给定情况提出了使用语言构造来避免它们的方法。 在本文中,“ 对象 ”一词用于指代类实例 ,因为“引用计数仅适用于类实例。 结构和枚举是值类型,而不是引用类型,并且不通过引用存储和传递。” 方案1: 对象通过属性相互引用,这两个属性都可以为“ nil` 它建议使用弱引用,以便在删除强引用时,将使用weak关键字声明的属性设置为nil 。 基类: 类人{ 命名:字符串 init(name:String){ 打印(“ \(名称)-开始初始化”) self.name =名称 } var apartment:公寓? deinit {print(“ \(name)正在被初始化”)} } 公寓类{ let单位:字符串 init(单位:字符串){ print(“ \(unit)-开始初始化”) self.unit =单位 } 弱var租户:人? deinit {print(“公寓\(单元)正在被初始化”)} } 创建变量和强引用: //注意可选的类型声明! var john:人吗? var unit4A:公寓? john = Person(姓名:“ […]