当前位置: 首页 > news >正文

网站制作的付款方式图片在线转外链

网站制作的付款方式,图片在线转外链,乐清做网站的公司,服装网站怎么做iOS内存管理 关于强引用循环 强引用循环是 ARC 无法自动处理的常见问题。如果两个对象互相强引用对方,就会造成引用计数不为零,导致对象无法释放。典型的情况是在闭包中引用 self 时,self 和闭包之间可能会互相持有,形成强引用循…

iOS内存管理

关于强引用循环

强引用循环是 ARC 无法自动处理的常见问题。如果两个对象互相强引用对方,就会造成引用计数不为零,导致对象无法释放。典型的情况是在闭包中引用 self 时,self 和闭包之间可能会互相持有,形成强引用循环。

解决方法: 使用 [weak self][unowned self] 来避免强引用循环,特别是在闭包内。

强引用(Strong Reference)是指一个对象在内存中持有对另一个对象的引用时,这个引用会增加被引用对象的引用计数。当一个对象的引用计数增加时,它的生命周期就被延长,直到引用计数变为零,表示没有任何对象引用它时,ARC 会自动释放这个对象的内存。

在 iOS 中,默认情况下,所有对象的引用都是强引用。强引用会导致引用的对象在内存中不会被释放,直到所有强引用都解除。

强引用的基本理解

  • 强引用:指对象通过 strong 持有另一个对象。该对象的生命周期会被引用方延长,直到引用方解除对它的持有。
  • 当两个对象之间通过强引用相互持有时,就会形成 强引用循环(Retain Cycle),这种情况下,即使它们不再需要对方,它们的引用计数也不会降到零,从而导致内存泄漏。

强引用的例子

1. 基本的强引用示例

假设你有两个对象:PersonCarPerson 强引用 Car,意味着只要 Person 存在,Car 就不会被释放。

class Person {var car: Car?
}class Car {var owner: Person?
}var john: Person? = Person()
var toyota: Car? = Car()john?.car = toyota
toyota?.owner = john

在这个例子中,john 对象强引用了 toyota 对象,同时 toyota 也强引用了 john 对象。由于两个对象互相持有对方,即使这两个对象的生命周期已经结束,它们的引用计数也不会变为零,因为它们彼此依赖,这就形成了 强引用循环。这会导致内存泄漏。

2. 解决强引用循环

可以通过使用 弱引用weak)来打破这种循环,确保当 PersonCar 不再需要时,它们能正确释放。

class Person {var car: Car?
}class Car {weak var owner: Person?  // 使用 weak 避免强引用循环
}var john: Person? = Person()
var toyota: Car? = Car()john?.car = toyota
toyota?.owner = john

在这个例子中,owner 属性使用 weak 修饰符,这样当 john 被释放时,toyota 中的 owner 引用就会变为 nil,从而打破强引用循环。

3. 强引用与内存管理的关系

当我们使用强引用时,ARC 会增加被引用对象的引用计数。下面是一个具体例子,说明如何影响内存管理:

class Dog {var name: Stringinit(name: String) {self.name = name}deinit {print("\(name) is being deinitialized")}
}var dog1: Dog? = Dog(name: "Buddy")
var dog2 = dog1  // dog2 强引用 dog1dog1 = nil  // dog1 被置为 nil,但是 dog2 仍然持有 Buddy 的引用

在上面的代码中:

  • dog1 被赋值为 nil 时,它不再持有 Buddy 对象。
  • 但是由于 dog2 仍然强引用着 BuddyBuddy 对象并不会立即被释放。
  • Buddy 只有当 dog2 也被置为 nil 后,才会释放内存。
4. 常见场景:闭包中的强引用

闭包是导致强引用循环的一个常见场景。例如,下面的代码就会导致强引用循环:

class ViewController: UIViewController {var someProperty: String = "Hello"func setupClosure() {let closure = {print(self.someProperty)  // 闭包捕获了 self}closure()}
}let vc = ViewController()
vc.setupClosure()

在上面的代码中,closure 捕获了 self(即 ViewController 的实例),这意味着 ViewController 对象将始终被闭包引用,self 的引用计数不会变为零,导致 ViewController 永远不会被释放。为了避免这种情况,我们通常使用 弱引用无主引用

func setupClosure() {let closure: () -> Void = { [weak self] inprint(self?.someProperty ?? "")}closure()
}

使用 [weak self] 来捕获 self,可以避免闭包对 ViewController 的强引用,从而避免强引用循环。

但需要注意的是,并不是所有的闭包都会产生强引用

不会产生强引用的情况

在闭包中使用 weakunowned 主要是为了避免 强引用循环(retain cycle),尤其是当闭包捕获 self 时。是否需要使用 weakunowned 取决于闭包与被捕获对象之间的生命周期关系。以下是几种情况,你可以根据这些情况来判断何时不需要使用 weakunowned

1. 闭包的生命周期比捕获的对象短

如果闭包的生命周期比被捕获的对象短(即闭包不会持有对象,且对象的生命周期不会依赖于闭包),则无需使用 weakunowned

示例

  • 闭包作为局部变量在方法内使用,并且被调用后立即销毁。
  • 闭包没有持有对对象的引用,且被调用时对象已被销毁。
class MyClass {var value = 10func performAction() {// 闭包在执行后立即销毁,不会产生强引用循环let closure = {print(self.value)}closure()}
}let obj = MyClass()
obj.performAction()

在这个例子中,闭包在方法内部执行时,仅仅是一个局部变量。它不会在方法外部持有 self,且方法执行完毕后,闭包就会被销毁,所以不需要使用 weakunowned 来捕获 self

2. 闭包被存储在对象的属性中,并且对象的生命周期与闭包相同

如果闭包是对象的一个属性,并且该对象的生命周期与闭包相同(即闭包和对象一起销毁),则也不需要使用 weakunowned

例如,闭包可能会作为一个委托回调、通知、或者是一些任务的完成闭包。如果该对象本身不会被提前销毁,闭包引用 self 是安全的,因为对象的生命周期会保持直到闭包不再需要。

示例

class Task {var completion: (() -> Void)?func start() {completion = {print("Task is done")}}
}let task = Task()
task.start()

在这个例子中,Task 对象持有 completion 闭包,闭包本身不会引发强引用循环,因为 Task 对象会一直存在直到 completion 被销毁。这里没有强引用循环问题。

3. 捕获的对象不会导致内存泄漏

如果闭包捕获的对象是一个“非持有”对象(例如全局对象、常量、静态对象),或者闭包执行时被捕获的对象本身在执行完成后就会被销毁(比如临时创建的对象),则不需要使用 weakunowned

示例

class MyClass {func fetchData() {let completion: () -> Void = {print("Data fetched!")}completion()}
}let instance = MyClass()
instance.fetchData()

在这个例子中,completion 闭包没有捕获 self,因此不会形成强引用循环。并且 completion 的生命周期非常短,执行完成后就会被销毁。

4. 闭包没有捕获 self

如果闭包本身不捕获 self(即没有使用 [weak self][unowned self]),且闭包本身不会导致引用循环,也可以不使用 weakunowned。这种情况下,闭包本身不会持有对象。

示例

class MyClass {var name = "Hello"func fetchData() {let completion: () -> Void = {print("Data fetched!")}completion()}
}let instance = MyClass()
instance.fetchData()

这里 completion 不捕获 self,所以 MyClass 对象不会因为闭包而延长生命周期。

总结:

我们需要注意闭包和实例是否会相互引用,还需要注意闭包和实例的生命周期

你不需要使用 weakunowned 来捕获 self 的情况包括:

  1. 闭包的生命周期比捕获的对象短,例如临时的局部闭包。
  2. 闭包被存储在对象属性中,并且对象的生命周期与闭包相同。
  3. 闭包没有捕获 self,且不涉及持有对象的引用。
  4. 捕获的对象不会导致内存泄漏,例如全局变量、常量等对象。
http://www.dtcms.com/a/572432.html

相关文章:

  • 平板网站开发环境长春制作手机网站
  • 网站点击量软件wordpress弹窗视频播放插件
  • 建一个网站需要多少时间表湛江企业网站建设流程
  • 有没有电商设计的网站参考wordpress 内容居中
  • 网站建设实训经验总结快速建站工具
  • 宁波网站排名提升北京市网站维护公司
  • 什么网站可以找手工活做宁夏建设网站的公司电话
  • 客户做外贸用那些网站怎样做企业的网站
  • 做网站要学什么语言godaddy主机wordpress
  • 长城宽带做网站一站式婚庆公司
  • 唐山手机网站建设网站建设页面底部叫什么
  • 主机怎么做网站服务器Wordpress pay plugin
  • 绿色网站建设背景的原因不适合学编程的人
  • 网站建设与维护服务wordpress 360字体大小
  • 哪些网站可以用来做百科参考浙江省建设政务网站
  • 迎访问中国建设银行网站-怎么做网站 ppt
  • 淘宝不能发布网站开发了贵阳app软件开发
  • 建立网站例题中山网站开发
  • 网站 使用的字体网络建设与管理好找工作吗
  • 哈尔滨做平台网站平台公司吗北京网页网站设计
  • 购物网站配色怎么设计ui培训机构推荐
  • 价格便宜的网站建设网站开发工程师的工作内容
  • 网站调试怎么用免费的网站空间
  • 做秩序册的网站seo经典案例
  • 株洲做网站公司南昌企业自助建站
  • 什么建站程序好收录石家庄网站建设成功案例
  • 制作一个网站的步骤教做网站的学校
  • 网站的模块福州网站设计哪家好
  • 北京南昌网站制作东莞市电池网站建设
  • 做网站的客户需求wordpress文档怎么制作