前言
循环引用:
*对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block中使用的对象:
*对于ARC下
为了防止循环引用, 我们使用__weak来修饰在Block中使用的对象。原理就是:ARC中,Block中如果引用了__strong修饰符的自动变量,则相当于Block对该变量的引用计数+1。
eg.:
内存泄露例子:
当在block内部使用成员变量的时候。那么block是会对内部的对象进行一次retain。也就是说,self会被retain一次。当self释放的时候,需要block释放后才会对self进行释放,但是block的释放又需要等self的dealloc中才会释放。如此一来变形成了循环引用,导致内存泄露。
修正
- (void)addGroup0{
// 1.弱引用成员变量或者控制器本事,防止block的循环引用
__weak HLShareViewController *share = self;
HLSettingItemGroupModel *group = [[HLSettingItemGroupModel alloc]init];
HLSettingArrowItemModel *sinaItem = [HLSettingArrowItemModel itemModelWithTitle:@"新浪分享" icon:@"WeiboSina" destVCClass:nil];
HLSettingArrowItemModel *smsItem = [HLSettingArrowItemModel itemModelWithTitle:@"短信分享" icon:@"SmsShare" destVCClass:nil];
//短信分享
[smsItem setOptionBlock:^{
//方式一:不能指定短信内容,不能自动回到原应用
// [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://188740548"]];
//方式二 :MessageUI框架--modal方法进行控制器间的切换
MFMessageComposeViewController *vc= [[MFMessageComposeViewController alloc]init];
// 设置短信内容
vc.body = @"lydia,中心藏之, 何以忘之";
// 设置收件人列表
vc.recipients = @[@"1887405", @"487"];
// 设置代理
vc.messageComposeDelegate = share;
// 显示控制器
if (vc) {
[share presentViewController:vc animated:YES completion:nil];//真机调试
}
}];
#define weakSelf(weakSelf) __weak __typeof(&*self)weakSelf = self;
block的好处:运行时才定义
block的定义格式
//block 的作用:保存一段代码,到恰当的时候调用,很多时候block是代理的一种优化方案
/*
0.block的介绍
Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。
1、定义
<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
<#statements#>
};
2.声明
typedef <#returnType#>(^<#name#>)(<#arguments#>);
3、内存管理--block本身是像对象一样可以retain,和release
1)block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。
他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃
2)解决这个问题的方法就是在创建完block的时候需要调用copy的方法。copy会把block从栈上移动到堆上,那么就可以在其他地方使用这个block了
4、循环引用
*对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block中使用的对象:
*对于ARC下, 为了防止循环引用, 我们使用__weak来修饰在Block中使用的对象。原理就是:ARC中,Block中如果引用了__strong修饰符的自动变量,则相当于Block对该变量的引用计数+1。
//定义weakself,方便在block中使用self
#define WS(weakSelf) __weak __typeof(&*self)weakSelf = self;
eg.:
__weak WebViewController *blockSelf = self; // 声明对象赋值self,使用__weak修饰,目的是在block内部使用的时候不会造成控制器引用计数+1
内存泄露例子:
当在block内部使用成员变量的时候。那么block是会对内部的对象进行一次retain。也就是说,self会被retain一次。当self释放的时候,需要block释放后才会对self进行释放,但是block的释放又需要等self的dealloc中才会释放。如此一来变形成了循环引用,导致内存泄露。
5、blocks 访问权限
1)blocks可以访问局部变量a,但是不能修改。
原因是在编译期间确定的,编译器编译的时候把a的值复制到block作为一个新变量(假设是a‘ = 10),此时a'和a是没有关系的。
2)如果要修改就要加关键字:__block或者static
6、block调用就像调用函数一样
//执行block
if (self.block) {
self.block(self.selectedBtn.tag);
}
7、block的定义
//定义block,通知导航控制器切换控制器
[tabBar setBlock:^(int index){
[self setSelectedIndex:index];//切换控制器
}];
// [tabBar.block copy];
*/
typedef void(^HLTabBarBlock)(int selectIndex);
@interface HLTabBar : UIView
@property (nonatomic,copy) HLTabBarBlock block;//--通知TabBar切换控制器
作者:u011018979 发表于2017/7/3 16:01:43 原文链接
阅读:27 评论:0 查看评论