IOS开发--循环引用问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东

所有的引用计数系统,都存在循环应用的问题。

例如下面的引用关系对象:

a创建并引用到了对象b.

对象b创建并引用到了对象c.

对象c创建并引用到了对象b.

这时候b和c的引用计数分别是2和1。当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中,造成内存浪费。这种情况,必须打断循环引用,通过其他规则来维护引用关系。

那么普通控件为什么要用weak:

如下图控制器中的View通过[self.view addSubview:btn];已经将Btn增加了强引用,所以不会被销毁,所以如果想把btn当做属性,没有必要在property中使用强引用浪费资源。

如果要用强引用也可以,因为在控制器销毁之后,控制器view也销毁了,所以btn销毁,不会造成强引用。

代理为什么要用weak如下图:

假设把代理设置成strong那么就会执行语句UIScrollView*scrollView=[UIScrollView alloc]init];scrollView.delegate=self;(self代表控制器)后,

当控制器想要销毁时,控制器被一个强指针指着,而scrollView添加到控制器view中也被强指针指着,也无法销毁,那么它的delegate不会销毁。delegate指向控制器。造成了循环引用。把delegate变成weak:当控制器生命周期结束时,view随之销毁,内部子空间也随之销毁,delegate也就销毁了。

block内用到了外面的东西,需要转换成weak指针,否则会造成循环引用 如下图:

有这样一段代码,代码本意不必理解:mail有一个block属性,那么block内有个邮件控制器需要设置代理。

ShareViewController内部强指针指向用Group,Group内部的items强指针指向mail对象,mail对象有个option属性(block),option内部用到了self也就是控制器,所以block(option是copy类型的)会用一个强指针指向self。注意:这里不和上边一样,不要被vc的代理(代理是weak的)所迷惑,是block强指针指向了self。造成了循环引用谁都没办法被销毁。

解决办法:使用:

__unsafe_unretained typeof(self) selfVc =self;

__unsafe_unretained HYShareViewController *selfVc =self;在block中让他对self只能进行弱引用。

或者把__unsafe_unretain改成__weak。(__unsafe_unretain和__weak的区别请见下一篇<OC语法--__unsafe_unretain、__strong、__weak、__autoreleasing这四种属性的作用>)

HYSettingItem *mail = [HYSettingArrowItemitemWithIcon:@"MailShare"title:@"邮件分享"destVcClass:nil];

mail.option = ^{

//不能发邮件

if (![MFMailComposeViewControllercanSendMail])return;

MFMailComposeViewController *vc = [[MFMailComposeViewControlleralloc]init];

[vcsetSubject:@"会议"];

[vc setMessageBody:@"今天下午开会吧"isHTML:NO];

vc.mailComposeDelegate = selfVc;

//显示控制器

[selfVc presentViewController:vcanimated:YEScompletion:nil];

};

HYSettingGroup *group = [[HYSettingGroupalloc]init];

group.items =@[sina, sms, mail];

[self.dataaddObject:group];

}

时间: 2024-08-03 02:46:10

IOS开发--循环引用问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东的相关文章

iOS开发基础篇-手写控件

一.手写控件的步骤 1)使用相应的控件类创建控件对象: 2)设置该控件的各种属性: 3)添加空间到视图中: 4)如果是 UIButton 等控件,还需考虑控件的单击事件等: 二.添加 UIButton 单击事件  [topbtn addTarget:self action:@selector(move:) forControlEvents:UIControlEventTouchUpInside]; 1) addTarget:forControlEvents: 方法定义在 UIControl 类中

iOS开发UI篇—手写控件,frame,center和bounds属性

iOS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View Contollor和view的关系 2.注意点 在OC开发中,Storyboard中的所有操作都可以通过代码实现,程序员一定要熟练掌握代码布局界面的能力! 设置控件监听方法的示例代码如下: [btn addTarget:se

IOS开发基础篇--手写控件,frame,center和bounds属性

iOS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View Contollor和view的关系 2.注意点 在OC开发中,Storyboard中的所有操作都可以通过代码实现,程序员一定要熟练掌握代码布局界面的能力! 设置控件监听方法的示例代码如下: [btn addTarget:se

iOS开发项目篇—43子控件的细节处理

iOS开发项目篇—43子控件的细节处理 一.升级UI 把之前的UI图片删除,换上新的图片(图片命名一致,规范)没有其他的影响. 删除之后,添加. 替换之后,做一次clear操作. 建议把沙盒中的包删除,删除之后再做一次clear操作. 二.调整转发(模块) 1.设置背景(使用提供的素材图片进行平铺) 为转发微博部分设置背景,考虑到这个部分整体上是一个UIView,可以尝试以下设置. 第一种尝试: 但是这样设置,因为图片是平铺的,所以整个背景会出现线条效果,影响显示,不可行. 第二种尝试: 注意:

iOS开发之如何获取各种控件的输入值

如何对各种控件进行操作,获取值以及赋值操作是iOS开发中最基本的技能,现在我们对输入框(Text Field),分段控件(Segmented Control),日期控件(Date Picker),滑块(Slider),开关控件(Switch),文本输入(Text View)等控件进行操作.通过一个小例子来进行该功能,用户输入个人信息,然后程序再把输入的信息获取并显示. (1)界面设计如下: . (2)把界面中的控件绑定到代码中,Outlet属性如下: . (3)把滑块和确定按钮设置Action动

iOS开发UI基础—手写控件,frame,center和bounds属性

一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View Contollor和view的关系 2.注意点 在OC开发中,Storyboard中的所有操作都可以通过代码实现,程序员一定要熟练掌握代码布局界面的能力! 设置控件监听方法的示例代码如下: [btn addTarget:self action:@selector(click:) forContro

iOS开发之代码创建常用控件(UIButton、UILabel)的思路

代码创建按钮UIButton: (一)基本设置 //创建中间“+”按钮 UIButton *addBtn = [[UIButton alloc] init]; //设置默认背景图片 [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon"] forState:UIControlStateNormal]; //设置按下时背景图片 [addBtn setBackgroundImage:[UIImage imageName

IOS开发UI篇--常用UI控件的基本使用

一. UIButton概述: UIKit框架提供了非常多的UI控件,其中有些控件天天使用,比如UIButton.UILabel.UIImageView.UITableView等. UIButton,俗称“按钮”,通常点击某个控件后,会做出相应反应的都是按钮.按钮的功能较多,既能显示图片又能显示汉字还能随时调整图片的文字和位置,如下面两个图 团购和音乐播放器的app: 下面本文通过一个实例总结一下它们的基本使用. 二. 按钮的基本设置 按钮既可以通过mainstoryboard创建也可以通过代码创

【iOS开发-12】UISwitch开关控件属性介绍以及获取开关状态并做出响应

(1)UISwitch的大小也是固定的,不随我们frame设置的大小改变:也是裁剪成圆角的,设置背景就露马脚发现背景是矩形. (2)UISwitch的背景图片设置无效,即我们只能设置颜色,不能用图片当背景,虽然实验了很小的图片,也是不行.可能需要借助第三方类来实现. (3)UISwitch也可以增加addTarget:方法,来获取值变动的操作,从而做出响应的反应. (4).isOn属性比较特殊,不能设置值,因为是哥getter方法,不是setter方法,所以只能获取值,例如判断是否开启,一般用在