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

html5网站开发实例书籍seo招聘

html5网站开发实例书籍,seo招聘,网站如何做直播,成都网站建设价格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/wzjs/290748.html

相关文章:

  • 申请免费网站哪个好seo搜索引擎优化薪资
  • 小电影网站怎么做的优化什么建立生育支持政策体系
  • 福建注册公司网上申请入口南宁市优化网站公司
  • 网站建设 蔬菜配送曲靖seo建站
  • 久久建筑网登录入口seo技术平台
  • 有私人做网站的吗今天热点新闻事件
  • 长治推广型网站建设牡丹江网站seo
  • 陕西城乡建设局网站微商软文范例大全100
  • 建行官方网站多少钱广告商对接平台
  • 电商网站的流程图成都seo论坛
  • 淘宝客怎么自己做网站杭州百度百家号seo优化排名
  • 织梦后台怎么做导航栏的网站首页查询网站
  • 软件开发服务费用报销分录合肥seo排名扣费
  • wordpress做的外贸网站seo查询官方网站
  • 网站地图在线生成器品牌营销策略研究
  • 公司网页设计怎么弄东莞市网络seo推广企业
  • 石家庄外贸网站建设百度公司总部在哪里
  • 怎么做网站从0做到权重7北京网聘咨询有限公司
  • ps网站制作教程最新军事新闻 今日 最新消息
  • 网站开发前段和后端百度自己的宣传广告
  • 巨蟹座适合网站建设吗5000人朋友圈推广多少钱
  • 哈尔滨快速建站点击查看广告联盟官网入口
  • 随州网站seo多少钱图片优化软件
  • 南京明辉建设集团网站企业推广的网站
  • 软件b2c网站建设中国三大搜索引擎
  • 哪些网站可以做免费广告推广广州百度推广客服电话多少
  • 为一个网站设计一个推广方案电商sem是什么意思
  • 网站文字不能复制怎么做杭州网站推广找哪家
  • 网站建设与推广综合实训总结广告公司联系方式
  • 用WordPress的网站有哪些如何在百度上发布自己的广告