iOS中代理属性为什么要用Weak修饰?
一.写在前面
代理设计模式,在iOS开发过程中,是一个非常常见的设计模式,可以说用的范围非常广泛,而对初学者来讲,常常对代理的属性修饰用weak存在疑惑,因此下面就解释一下其中非常简单的道理.
二.必要的知识补充.
- 众所周知,OC是一门面向对象的语言,因此,对象这个词,在iOS中是个非常重要的词汇了(扯淡).开发中,创建一个对象是再常见不过的事儿了,每个对象的创建都需要在内存中分配一定的空间,简单的说,因为内存是有限的,所以一些没有必要存在的对象,我们需要及时的去将它释放,还原更多的内存空间(如果不进行释放就会造成"内存泄露").
- 因此,在iOS中引入了引用计数(retainCount)这个词汇,规定:只要引用计数为零,对象就会被释放,注意是规定,规定就不要问为什么了.
- 这里主要介绍strong和weak两个修饰词(不能偏离重点),如果想了解其他的修饰词(retain,copy,getter,setter...),可以Google一下,简单点来讲strong属性会使引用计数+1,而weak修饰的对象不会使引用计数改变.
- OK了,有了上面的只是准备,应该可以理解下面的要解释的东西了.
三.案例说明
案例介绍
案例中的类介绍: 案例共用到三个类,Baby类(婴儿类),LLBabyServant类(保姆类),ViewControllr类(控制器类),其中说明问题的关键是之前两个类.
假设,婴儿类要想做一些事情(像换衣服了,方便了之类的...)就必须具有代理的属性,因此指定了一个协议<LLBabyDelegate>,合情合理.而保姆需要成为婴儿的代理,必须遵循协议,废话不多说,上代码!
首先介绍Baby类-----.h文件
// 制定协议
@protocol LLBabyDelegate <NSObject>
//这里可以编写代理方法(该案例中用不到所以就不写了)
@end @interface Baby : NSObject
/**
* baby的代理属性(这里用的是weak修饰,正确的做法)
*/
@property(nonatomic, weak) id<LLBabyDelegate>delegate;
@end说明:跟上面描述的一样婴儿拥有一个代理的属性.并且用修饰词Weak修饰的.
接着粘Baby类-----.m文件
@implementation Baby
- (void)dealloc
{
NSLog(@"Baby被销毁了");
}
@end
说明:该方法的作用是当该类的对象被销毁时会调用-dealloc方法(在这个案例中用来观察对象是否被销毁了)
再有介绍BabyServant类-----.m文件
//BabyServant类也就是保姆必须遵循代理协议
@interface BabyServant()<LLBabyDelegate>
//并有一个需要照顾的Baby
@property(nonatomic, strong) Baby *baby; @end @implementation LLBabyServant
//初始化方法
- (instancetype)init
{
self = [super init]; if (self) {
// 初始化'婴儿'对象
self.baby = [[Baby alloc]init];
// 设置'自己(LLBabyServant)'为(Baby)类的代理
self.baby.delegate = self;
} return self;
}
我们介绍最后一个类 ViewController类
@implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; LLBabyServant *servant = [[LLBabyServant alloc]init]; } @end说明: 在ViewController的方法ViewDidLoad中创建保姆对象,并且该对象作用的范围是这个方法内部.这个方法执行完成,servant对象就会被销毁了.
上面的代码执行完成之后,运行结果如下:
2016-02-18 15:06:41.151 代理weak案例[1805:173874] LLBabyServant 被销毁了
2016-02-18 15:06:41.152 代理weak案例[1805:173874] Baby类被销毁了
这就说明LLBabyServant对象和Baby对象在没有用处之后都会被销毁,但是如果用代理用strong修饰,而不是用weak修饰,则不会打印上面的结果!
四.分析
用weak分析图如下:
如果weak的话,在程序运行的时候不会造成循环引用,对象都会被顺利的销毁,所以会调用婴儿类和保姆类的delloc方法,
用strong分析如下
如果strong的话,在程序运行的时候会造成循环引用(意思就是reatainCount不为0,只要有实线引用,计数器就+1),对象都不会的销毁,所以会调用婴儿类和保姆类不会调用delloc方法,从而造成了内存泄露的问题,
这就是为什么代理属性要用weak修饰的原因了,希望能帮到你们!
iOS中代理属性为什么要用Weak修饰?的更多相关文章
- iOS中常用属性的关键字的使用说明
属性关键字的作用 现在我们iOS开发中,基本都是使用ARC(自动引用计数)技术,来编写我们的代码.因此在属性property中我们经常使用的关键字有strong,weak,assign,copy,no ...
- IOS中的属性列表----Property List
属性列表,是一种用来存储串行化后的对象的文件.因为扩展名为plist ,因此通常被称为 plist文件. plist文件通常用于储存用户设置,也可以用于存储捆绑的信息,其内容为xml格式.它可以在程序 ...
- iOS中文本属性Attributes
NSFontAttributeName //设置字体大小 NSParagraphStyleAttributeName //设置段落格式 NSForegroundColorAttributeName / ...
- iOS - Delegate 代理
1.Delegate 1.1 协议 协议:是多个类共享的一个方法列表.协议中列出的方法没有相应的实现,计划由其他人来实现.协议中列出的方法,有些是可以选择实现,有些是必须实现. 1>.如果你定义 ...
- IOS中UIScrollView的详细使用
UIScrollView 是可以滚动的View 要想让UIScrollView可以滚动,必须设置UIScrollView的contentSize contentSize : 表示UIScrollVie ...
- ios中strong, weak, assign, copy
copy 和 strong(retain) 区别 1. http://blog.csdn.net/itianyi/article/details/9018567 大部分的时候NSString的属性都是 ...
- IOS开发中ARC下的assign和weak区别
在ARC中的assign和weak可以说非常相像,导致有很多人误以为他们是一摸一样的,在任何时候都可以划等价,但事实却不是这样. 在群里,有人问,id类型的delegate属性到底是用assign还是 ...
- iOS中UIPickerView常见属性和方法的总结
UIPickerView是iOS中的原生选择器控件,使用方便,用法简单,效果漂亮. @property(nonatomic,assign) id<UIPickerViewDataSource&g ...
- ios 中直接修改frame里边某个属性的简便方法
参考:http://www.cnblogs.com/wengzilin/p/4359865.html 在iOS中view的frame属性使用地太频繁了,尤其是调UI的时候.我们知道,正常情况下我们无法 ...
随机推荐
- 从零开始Windows环境下安装python+tensorflow
从零开始Windows环境下安装python+tensorflow 2017年07月12日 02:30:47 qq_16257817 阅读数:29173 标签: windowspython机器学习te ...
- VM虚拟机安装windows7操作系统
一.创建虚拟机 1. 新建虚拟机 2. 默认配置,点击下一步 3. 稍后安装操作系统,下一步 4. 选择操作系统,32位选择windows 7,64位选择windows 7 x64,点击下一步 5. ...
- 用UICollectionView实现上下轮播的案例
// // RecommendNewsCell.swift // XMLYFM // // Created by Domo on 2018/8/2. // Copyright © 2018年 ...
- 老出BUG怎么办?游戏服务器常见问题解决方法分享
在游戏开发中,我们经常会遇到一些技术难题,而其引发的bug则会影响整个游戏的品质.女性向手游<食物语>就曾遇到过一些开发上的难题,腾讯游戏学院专家团Wade.Zc.Jovi等专家为其提供了 ...
- Linux笔记01
linux目录结构 : linux只有一个目录. usr:等价于programfiles: etc:存放系统配置 root:管理员(超级用户)目录, home:存放其他用户的目录: lib:共享包: ...
- day26(026-网络编程)
###26.02_网络编程(网络编程三要素之IP概述) IPv6:8组,每组4个16进制数. 1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f ###26.03_网络编程 ...
- mysql5.7.21源码安装
1.下载安装包 MySQL 官方下载地址:https://dev.mysql.com/downloads/mysql/ MySQL 5.7官方安装文档:https://dev.mysql.com/d ...
- requests.get()///post函数///base64函数
1.requests.get() 一般的用法:r=requests.get(url) 或者是用上session: r=requests.session() r=r.get(url) get()收集的是 ...
- spyder.app制作图标
安装了 anaconda3, 自带spyder, 但是只能在terminal 中打开, 非常不友好. 模仿 anaconda3/目录下 Anaconda-Navigator.app, 制作了 spyd ...
- Go语言-并发模式-资源池实例(pool)
Go语言并发模式 利用goroutine和channel进行go的并发模式,实现一个资源池实例(<Go语言实战>书中实例稍作修改) 资源池可以存储一定数量的资源,用户程序从资源池获取资源进 ...