Block的在未引用外部变量时,存储过程引用变量在哪个内存区域

C。定义块的时候,所占的内存区域是分配在栈中,块只在它定义的范围内有效。一旦离开相应范围,编译器就有可能会把这部分内存区域给覆写。使用copy后,会将block复制到堆上。
我在看这题的解析的时候,为什么底下的广告飘上来了,网站的bug???
不是block内部引用外部的局部变量时才会在栈内存上吗?
不管在ARC还是MRC环境下,block内部如果没有访问外部变量,这个block是全局block__NSGlobalBlock__,形式类似函数,存储在内存中的代码区。
在MRC下,block内部如果访问外部变量,这个block是栈block__NSStackBlock__,存储在内存中的栈上。
在MRC下,block内部访问外部变量,同时对该block做一次copy操作,这个block是堆block__NSMallocBlock__,存储在内存中的堆上。
在ARC下,block内部如果访问外部变量,这个block是堆block__NSMallocBlock__,存储在内存中的堆上,因为在ARC下,默认对block做了一次copy操作
OC的block一共有三种 block ,globalblock 没有引用外部变量时是存在全局区啊
这道题个人觉得有些问题!在ARC下,block也是有三种类型的。没有引用外部变量是全局的block,存放在全局区的。而栈区的block是那种匿名的引用了外部变量,堆区的block是可以通过block名调用并引用了外部变量的一类。
这道题你会答吗?花几分钟告诉大家答案吧!
扫描二维码,关注牛客网
下载牛客APP,随时随地刷题
京ICP备号-4
扫一扫,把题目装进口袋大清铜币户部戊申粤字值多少钱 _ 赤峰汽车网
大清铜币户部戊申粤字值多少钱
量巨大,十元左右一枚,专骗小白。品相好的稀有品种最高上千,母币上十万,他们自拍自买自导自演的噱头。不能相信网上骗子公司骗人的假新闻
这要看你的交易方式,至于价值如何,是收购还是私下交易或者拍卖;你要出手这个要看实物来决定的,价格上是不一样的,希望我的回答对你有所帮助,价格在几万到几十万之间浮动,甚至有可能过百万
这个要看实物来决定的,至于价值如何,这要看你的交易方式,是收购还是私下交易或者拍卖,价格上是不一样的,价格在几万到几十万之间浮动,甚至有可能过百万,希望我的回答对你有所帮助;你要出手?
比较常见的大清铜币,市场价在10元左右。
户部戊申大清铜币中心粤十文背光绪上佳品市价10--15元 户部戊申大清铜币中心粤十文背光绪美品市价20--30元 户部戊申大清铜币中心粤十文背光绪优美品市价40--50元
戊申户部大清铜币中心“粤”当制钱十文值5元到100之间!希望能帮到你!
您的问题,这样的铜圆品种,大清铜币戊申中间 粤 字,十文,真品常见版式品相好的市场上一般在100元左右;真品喜欢就可以当一个品种收藏!
2--10元一个。
光绪铜元背龙普品二十元左右
戊申户部大清铜币中心“粤”当制钱十文,普品10-20元
返回主页:
本文网址:http://www.0476car.cn/view-.html我在看这题的解析的时候,为什么底下的广告飘上来了,网站的bug???
不是block内部引用外部的局部变量时才会在栈内存上吗?
不管在ARC还是MRC环境下,block内部如果没有访问外部变量,这个block是全局block__NSGlobalBlock__,形式类似函数,存储在内存中的代码区。
在MRC下,block内部如果访问外部变量,这个block是栈block__NSStackBlock__,存储在内存中的栈上。
在MRC下,block内部访问外部变量,同时对该block做一次copy操作,这个block是堆block__NSMallocBlock__,存储在内存中的堆上。
在ARC下,block内部如果访问外部变量,这个block是堆block__NSMallocBlock__,存储在内存中的堆上,因为在ARC下,默认对block做了一次copy操作
C。定义块的时候,所占的内存区域是分配在栈中,块只在它定义的范围内有效。一旦离开相应范围,编译器就有可能会把这部分内存区域给覆写。使用copy后,会将block复制到堆上。
OC的block一共有三种 block ,globalblock 没有引用外部变量时是存在全局区啊
这道题个人觉得有些问题!在ARC下,block也是有三种类型的。没有引用外部变量是全局的block,存放在全局区的。而栈区的block是那种匿名的引用了外部变量,堆区的block是可以通过block名调用并引用了外部变量的一类。
这道题你会答吗?花几分钟告诉大家答案吧!
扫描二维码,关注牛客网
下载牛客APP,随时随地刷题
京ICP备号-4
扫一扫,把题目装进口袋Block内存管理实例分析
招聘信息:
说道block大家都不陌生,内存管理问题也是开发者最头疼的问题,网上很多讲block的博客,但大都是理论性多点,今天结合一些实例来讲解下。存储域首先和大家聊聊block的存储域,根据block在内存中的位置,block被分为三种类型:NSGlobalBlockNSStackBlockNSMallocBlock从字面意思上大家也可以看出来NSGlobalBlock是位于全局区的block,它是设置在程序的数据区域(.data区)中。NSStackBlock是位于栈区,超出变量作用域,栈上的Block以及 &__block变量都被销毁。NSMallocBlock是位于堆区,在变量作用域结束时不受影响。注意:在 ARC 开启的情况下,将只会有 NSConcreteGlobalBlock 和 NSConcreteMallocBlock 类型的 block。说了这么多理论的东西,有些人可能很懵,觉得讲这些有什么用呢,我平时使用block并没有什么问题啊,好了,接下来我们先来个感受下:#import&"ViewController.h"
void(^block)(void);
@implementation&ViewController
-&(void)viewDidLoad&{
&&&&[super&viewDidLoad];
&&&&NSInteger&i&=&10;
&&&&block&=&^{
&&&&&&&&NSLog(@"%ld",&i);
-&(void)touchesBegan:(NSSet&*)touches&withEvent:(UIEvent&*)event&{
&&&&block();
@end声明这样一个block,点击屏幕的时候去调用这个block,然后就会发生以下错误:野指针错误,显而易见,这个是生成在栈上的block,因为超出了作用域而被释放,所以再调用的时候报错了,通过打印这个block我们也可以看到是生成在栈上的:解决办法解决办法呢有两种:Objective-C为块常量的内存管理提供了复制(Block_copy())和释放(Block_release())命令。 使用Block_copy()命令可以将块常量复制到堆中,这就像实现了一个将块常量引用作为输入参数并返回相同类型块常量的函数。-&(void)viewDidLoad&{
&&&&[super&viewDidLoad];
&&&&NSInteger&i&=&10;
&&&&block&=&Block_copy(^{
&&&&&&&&NSLog(@"%ld",&i);
}为了避免内存泄漏,Block_copy()必须与相应的Block_release()命令达到平衡:Block_release(block);Foundation框架提供了处理块的copy和release方法,这两个方法拥有与Block_copy()和Block_release()函数相同的功能:-&(void)viewDidLoad&{
&&&&[super&viewDidLoad];&&&&NSInteger&i&=&10;
&&&&block&=&[^{&&&&&&&&NSLog(@"%ld",&i);
&&&&}&copy];
}[block&release];到这里有人可能会有疑问了,为什么相同的代码我建了一个工程,没有调用copy,也没有报错啊,并且可以正确打印。 那是因为我们上面的操作都是在MRC下进行的,ARC下编译器已经默认执行了copy操作,所以上面的这个例子就解释了Block超出变量作用域可存在的原因。接下来可能有人又要问了,block什么时候在全局区,什么时候在栈上,什么时候又在堆上呢?上面的例子是对生成在栈上的Block作了copy操作,如果对另外两种作copy操作,又是什么样的情况呢?通过这张表我们可以清晰看到三种Block copy之后到底做了什么,接下来我们就来分别看看这三种类型的Block。NSGlobalBlock在记述全局变量的地方使用block语法时,生成的block为_NSConcreteGlobalBlock类对象void(^block)(void)&=&^&{&NSLog(@"Global&Block");};
int&main()&{
}在代码不截获自动变量时,生成的block也是在全局区:int(^block)(int&count)&=&^(int&count)&{
&&&&&&&&return&
&block(2);但是通过clang改写的底层代码指向的是栈区:impl.isa&=&&_NSConcreteStackBlock这里引用巧神的一段话:由于 clang 改写的具体实现方式和 LLVM 不太一样,并且这里没有开启 ARC。所以这里我们看到 isa 指向的还是_NSConcreteStackBlock。但在 LLVM 的实现中,开启 ARC 时,block 应该是 _NSConcreteGlobalBlock 类型总结下,生成在全局区block有两种情况:定义全局变量的地方有block语法时block语法的表达式中没有使用应截获的自动变量时NSStackBlock配置在全局区的block,从变量作用域外也可以通过指针安全地使用。但是设置在栈上的block,如果其作用域结束,该block就被销毁。同样的,由于__block变量也配置在栈上,如果其作用域结束,则该__block变量也会被销毁。上面举得例子其实就是生成在栈上的block:NSInteger&i&=&10;&
block&=&^{&
&&&&&NSLog(@"%ld",&i);&
};除了配置在程序数据区域的block(全局Block),其余生成的block为_NSConcreteStackBlock类对象,且设置在栈上,那么配置在堆上的__NSConcreteMallocBlock类何时使用呢?NSMallocBlockBlocks提供了将Block和__block变量从栈上复制到堆上的方法来解决这个问题,这样即使变量作用域结束,堆上的Block依然存在。impl.isa&=&&_NSConcreteMallocB这也是为什么Block超出变量作用域还可以存在的原因。那么什么时候栈上的Block会复制到堆上呢?调用Block的copy实例方法时Block作为函数返回值返回时将Block赋值给附有__strong修饰符id类型的类或Block类型成员变量时将方法名中含有usingBlock的Cocoa框架方法或GCD的API中传递Block时上面只对Block进行了说明,其实在使用__block变量的Block从栈上复制到堆上时,__block变量也被从栈复制到堆上并被Block所持有。接下来我们再来看一个????:void(^block)(void);
int&main(int&argc,&const&char&*&argv[])&{
&&&&@autoreleasepool&{
&&&&&&&&__block&NSInteger&i&=&10;
&&&&&&&&block&=&[^{
&&&&&&&&&&&&++i;
&&&&&&&&}&copy];
&&&&&&&&++i;
&&&&&&&&block();
&&&&&&&&NSLog(@"%ld",&i);
&&&&return&0;
}我们对这个生成在栈上的block执行了copy操作,Block和__block变量均从栈复制到堆上。然后在Block作用域之后我们又使用了与Block无关的变量:++i;一个是存在于栈上的变量,一个是复制到堆上的变量,我们是如何做到正确的访问这个变量值的呢?通过clang转换下源码来看下:void(*block)(void);
struct&__Block_byref_i_0&{
&&void&*__
__Block_byref_i_0&*__
&NSInteger&i;
struct&__main_block_impl_0&{
&&struct&__block_impl&
&&struct&__main_block_desc_0*&D
&&__Block_byref_i_0&*i;&//&by&ref
&&__main_block_impl_0(void&*fp,&struct&__main_block_desc_0&*desc,&__Block_byref_i_0&*_i,&int&flags=0)&:&i(_i->__forwarding)&{
&&&&impl.isa&=&&_NSConcreteStackB
&&&&impl.Flags&=&
&&&&impl.FuncPtr&=&
&&&&Desc&=&
static&void&__main_block_func_0(struct&__main_block_impl_0&*__cself)&{
&&__Block_byref_i_0&*i&=&__cself->i;&//&bound&by&ref
&&&&&&&&&&&&++(i->__forwarding->i);
static&void&__main_block_copy_0(struct&__main_block_impl_0*dst,&struct&__main_block_impl_0*src)&{_Block_object_assign((void*)&dst->i,&(void*)src->i,&8/*BLOCK_FIELD_IS_BYREF*/);}
static&void&__main_block_dispose_0(struct&__main_block_impl_0*src)&{_Block_object_dispose((void*)src->i,&8/*BLOCK_FIELD_IS_BYREF*/);}
static&struct&__main_block_desc_0&{
&&size_t&Block_
&&void&(*copy)(struct&__main_block_impl_0*,&struct&__main_block_impl_0*);
&&void&(*dispose)(struct&__main_block_impl_0*);
}&__main_block_desc_0_DATA&=&{&0,&sizeof(struct&__main_block_impl_0),&__main_block_copy_0,&__main_block_dispose_0};
int&main(int&argc,&const&char&*&argv[])&{
&&&&/*&@autoreleasepool&*/&{&__AtAutoreleasePool&__&
&&&&&&&&__attribute__((__blocks__(byref)))&__Block_byref_i_0&i&=&{(void*)0,(__Block_byref_i_0&*)&i,&0,&sizeof(__Block_byref_i_0),&10};
&&&&&&&&block&=&(void&(*)())((id&(*)(id,&SEL))(void&*)objc_msgSend)((id)((void&(*)())&__main_block_impl_0((void&*)__main_block_func_0,&&__main_block_desc_0_DATA,&(__Block_byref_i_0&*)&i,&)),&sel_registerName("copy"));
&&&&&&&&++(i.__forwarding->i);
&&&&&&&&((void&(*)(__block_impl&*))((__block_impl&*)block)->FuncPtr)((__block_impl&*)block);
&&&&&&&&NSLog((NSString&*)&__NSConstantStringImpl__var_folders_47_s4m8c9pj5mg0k9mymsm7rbmw0000gn_T_main_e69554_mi_0,&(i.__forwarding->i));
&&&&return&0;
}static struct IMAGE_INFO { } _OBJC_IMAGE_INFO = { 0, 2 };我们发现相比于没有__block关键字修饰的变量,源码中增加了一个名为 __Block_byref_i_0 的结构体,用来保存我们要 capture 并且修改的变量 i。在__Block_byref_i_0结构体中我们可以看到成员变量__forwarding,它持有指向该实例自身的指针。那么为什么会有这个成员变量__forwarding呢?这也是正是问题的关键。我们可以看到源码中这样一句:++(i->__forwarding->i);栈上的__block变量复制到堆上时,会将成员变量__forwarding的值替换为复制到堆上的__block变量用结构体实例的地址。所以“不管__block变量配置在栈上还是堆上,都能够正确的访问该变量”,这也是成员变量__forwarding存在的理由。循环引用循环引用比较简单,造成循环引用的原因无非就是对象和block相互强引用,造成谁都不能释放,从而造成了内存泄漏。基本的一些例子我就不再重复了,网上很多,也比较简单,我就一个问题来讨论下,也是开发中有人问过我的一个问题:block里面使用self会造成循环引用吗? &很显然答案不都是,有些情况下是可以直接使用self的,比如调用系统的方法:[UIView&animateWithDuration:0.5&animations:^{
&&&&&&&&NSLog(@"%@",&self);
&&&&}];因为这个block存在于静态方法中,虽然block对self强引用着,但是self却不持有这个静态方法,所以完全可以在block内部使用self。还有一种情况:当block不是self的属性时,self并不持有这个block,所以也不存在循环引用void(^block)(void)&=&^()&{
&&&&&&&&NSLog(@"%@",&self);
block();只要我们抓住循环引用的本质,就不难理解这些东西。,讲的很透彻,分析的很好!希望可以通过上面的一些例子,可以让大家加深对block的理解,知其然并且知其所以然。
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量3321点击量3298点击量2721点击量2226点击量2203点击量2144点击量2119点击量1996点击量1968
&2018 Chukong Technologies,Inc.
京公网安备8951CTO旗下网站
block 解析 - 内存
block结构体相应的也有一个成员引用,这样会增加对局部变量的 _para1引用,在Block销毁的时候引用就释放掉了
作者:Green来源:cnblogs| 11:12
我们了解到了用__block修饰的变量,可以在block内部修改,__block变量其实对应一个结构体
struct&__Block_byref__para1_0&{&&&void&*__&__Block_byref__para1_0&*__&&int&__&&int&__&&char&*_para1;&};&
block结构体相应的也有一个成员引用,这样会增加对局部变量的&_para1引用,在Block销毁的时候引用就释放掉了
struct&__main1_block_impl_0&{&&&struct&__block_impl&&&&struct&__main1_block_desc_0*&D&&&__Block_byref__para1_0&*_para1;&&
block内部 成员变量 使用,可以在block内部修改,对应一个、多个成员变量参数,block结构体内部有一个成员引用
struct&__KDBlockTest__test3_block_impl_0&{&&&struct&__block_impl&&&&struct&__KDBlockTest__test3_block_desc_0*&D&&&KDBlockTest&*&}&
这样会增加对self的引用,在Block销毁的时候引用就释放掉了
在使用的时候需要注意循环引用,即某个对象有一个copy或者strong的 block成员属性,这时block内部直接引用了 成员变量(全局变量) 或者self,这样就产生了self持有 block成员,block成员又持有了self,就会导致循环引用。
我们看以下代码(ARC):
typedef&void(^ActionTest)(void);&@interface&KDBlockTest()&{&&&&&__block&NSString&*_person2;&&&&&ActionTest&_&}
@implementation&KDBlockTest&#pragma&mark&-&system&-(instancetype)init&{&&&&&self=[super&init];&&&&&if(self)&&&&&{&&&&&&&&&[self&test3];&&&&&}&&&&&return&&}&-(void)dealloc&{&&&&&NSLog(@&KDBlockTest&dealloc&);&}&&#pragma&mark&-&private&&-(void&)test3&{&&&&&_person2=@&person2&;&&&&&_action=&^(void)&{&&&&&&&&&&&&&&&&&&NSLog(@&excuteing&_person2:%@,%p&,_person2,_person2);&&&&&};&&&&&_action();&}&
这样我们执行以下代码:
KDBlockTest&*_test=[[KDBlockTest&alloc]init];&
通过调试发现没有走到dealloc,这里不管成员变量&_person2 是否声明&__block都没有什么影响。
&这一篇已经详细介绍了,对于block 使用 成员变量、self来说,block内部是直接强引用self的。也就是block持有了self,在这里bock又作为self的一个成员被持有,所以就形成了相互引用,导致无法释放。
对于上面这种情况,我们引入了__weak解决,__weak不会增加对象的引用计数,而且当指向的内存销毁后,__weak指针会自动置为nil。
我们对上面的代码稍作修改
-(void&)test3&{&&&&&__weak&typeof(self)&_weakSelf=&&&&&_person2=@&person2&;&&&&&NSLog(@&init:%@,%p,%p&,_person2,_person2,&self);&&&&&_action=&^(void)&{&&&&&&&&&&&&&&&&&&NSLog(@&excuteing&_person2:%@,%p,%p&,_weakSelf.person2,_weakSelf.person2,&_weakSelf);&&&&&};&&&&&_action();&}&
输出日志:
2014-07-29 13:38:30.872 Test[2642:60b] init:person2,0x5b980,0x27dae944
2014-07-29 13:38:30.875 Test[2642:60b] excuteing _person2:person2,0x5b980,0x1562ed44
2014-07-29 13:38:30.876 Test[2642:60b] KDBlockTest dealloc
从日志可以看出block内部使用 person2 、_weakSelf 和外面的 person2 、self 地址是一样的,看来也是引用关系,既达到block内部修改变量的效果,又没有对变量产生强引用。我们来看下转换后的代码:
block结构体的定义:
struct&__KDBlockTest__test3_block_impl_0&{&&&struct&__block_impl&&&&struct&__KDBlockTest__test3_block_desc_0*&D&&&__weak&typeof&(self)&_weakS&&&__KDBlockTest__test3_block_impl_0(void&*fp,&struct&__KDBlockTest__test3_block_desc_0&*desc,&__weak&typeof&(self)&__weakSelf,&int&flags=0)&:&_weakSelf(__weakSelf)&{&&&&&impl.isa&=&&_NSConcreteStackB&&&&&impl.Flags&=&&&&&&impl.FuncPtr&=&&&&&&Desc&=&&&&}&};&
重点就在这,使用_weak声明的self,block结构体对应 也生成了一个_weak的self成员。我们在看下 我们的test3 方法:
static&void&_I_KDBlockTest_test3(KDBlockTest&*&self,&SEL&_cmd)&{&&&&&__attribute__((objc_gc(weak)))&typeof(self)&_weakSelf=&&&&&(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2))=(NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_d10f18_mi_1;&&&&&NSLog((NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_d10f18_mi_2,(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)),(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)),&self);&&&&&(*(ActionTest&*)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_action))=&(void&(*)())&__KDBlockTest__test3_block_impl_0((void&*)__KDBlockTest__test3_block_func_0,&&__KDBlockTest__test3_block_desc_0_DATA,&_weakSelf,&);&&&&&((void&(*)(__block_impl&*))((__block_impl&*)(*(ActionTest&*)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_action)))-&FuncPtr)((__block_impl&*)(*(ActionTest&*)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_action)));&}&
block初始化的时候把 &_weakSelf的地址传入,block内部对_weakSelf进行弱引用。在执行block的时候
static&void&__KDBlockTest__test3_block_func_0(struct&__KDBlockTest__test3_block_impl_0&*__cself)&{&&&__weak&typeof&(self)&_weakSelf&=&__cself-&_weakS&&&&&&&&&&&&NSLog((NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_d10f18_mi_3,((NSString&*(*)(id,&SEL))(void&*)objc_msgSend)((id)_weakSelf,&sel_registerName(&person2&)),((NSString&*(*)(id,&SEL))(void&*)objc_msgSend)((id)_weakSelf,&sel_registerName(&person2&)),&_weakSelf);&&&&&}&
通过取得block结构体的 弱引用对象self 成员来访问相对应的方法&person2 (给对象发消息)。
上面例子,我们稍作修改:
(void&)test3&{&&&&&_person2=@&person2&;&&&&&__weak&typeof(_person2)&_weakPerson2=_person2;&&&&&NSLog(@&init:%@,%p,%p&,_person2,_person2,&_person2);&&&&&NSLog(@&init&weak:%@,%p,%p&,_weakPerson2,_weakPerson2,&_weakPerson2);&&&&&_action=&^(void)&{&&&&&&&&&&&&&&&&&&&&NSLog(@&excuteing&_person2:%@,%p,%p&,_weakPerson2,_weakPerson2,&_weakPerson2);&&&&&};&&&&&_person2=@&person22&;&&&&&NSLog(@&before:%@,%p,%p&,_person2,_person2,&_person2);&&&&&NSLog(@&before&weak:%@,%p,%p&,_weakPerson2,_weakPerson2,&_weakPerson2);&&&&&_action();&&&&&NSLog(@&after:%@,%p,%p&,_person2,_person2,&_person2);&}&
输出日志:
2014-07-29 15:29:33.472 Test[2719:60b] init:person2,0x5397c,0x16566db8
2014-07-29 15:29:33.475 Test[2719:60b] init weak:person2,0x5397c,0x27db693c
2014-07-29 15:29:33.476 Test[2719:60b] before:person22,0x539bc,0x16566db8
2014-07-29 15:29:33.477 Test[2719:60b] before weak:person2,0x5397c,0x27db693c
2014-07-29 15:29:33.479 Test[2719:60b] excuteing _person2:person2,0x5397c,0x165b5be4
2014-07-29 15:29:33.480 Test[2719:60b] after:person22,0x539bc,0x16566db8
2014-07-29 15:29:33.481 Test[2719:60b] KDBlockTest dealloc
从日志可以看出:
直接用__weak修饰符修饰_person2变量也可以,也可以避免循环引用,但是不可以在block内部修改外部 参数的值
在block外部修改变量指针指向,即把指针指向另外一块内存,block内部无法更新到。
我们来看下转换后的代码:其实和不加__block的局部变量差不多,无非多了一个弱引用,不会对引用计数有影响。
struct&__KDBlockTest__test3_block_impl_0&{&&&struct&__block_impl&&&&struct&__KDBlockTest__test3_block_desc_0*&D&&&__weak&typeof&(self-&_person2)&_weakPerson2;&&&__KDBlockTest__test3_block_impl_0(void&*fp,&struct&__KDBlockTest__test3_block_desc_0&*desc,&__weak&typeof&(self-&_person2)&__weakPerson2,&int&flags=0)&:&_weakPerson2(__weakPerson2)&{&&&&&impl.isa&=&&_NSConcreteStackB&&&&&impl.Flags&=&&&&&&impl.FuncPtr&=&&&&&&Desc&=&&&&}&};&
static&void&_I_KDBlockTest_test3(KDBlockTest&*&self,&SEL&_cmd)&{&&&&&&(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2))=(NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_f32cef_mi_1;&&&&&&__attribute__((objc_gc(weak)))&typeof(_person2)&_weakPerson2=(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2));&&&&&NSLog((NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_f32cef_mi_2,(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)),(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)),&(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)));&&&&&NSLog((NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_f32cef_mi_3,_weakPerson2,_weakPerson2,&_weakPerson2);&&&&&&(*(ActionTest&*)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_action))=&(void&(*)())&__KDBlockTest__test3_block_impl_0((void&*)__KDBlockTest__test3_block_func_0,&&__KDBlockTest__test3_block_desc_0_DATA,&_weakPerson2,&);&&&&&(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2))=(NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_f32cef_mi_5;&&&&&NSLog((NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_f32cef_mi_6,(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)),(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)),&(*(NSString&**)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_person2)));&&&&&NSLog((NSString&*)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_f32cef_mi_7,_weakPerson2,_weakPerson2,&_weakPerson2);&&&&&((void&(*)(__block_impl&*))((__block_impl&*)(*(ActionTest&*)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_action)))-&FuncPtr)((__block_impl&*)(*(ActionTest&*)((char&*)self&+&OBJC_IVAR_$_KDBlockTest$_action)));&}&
在声明 _weak变量的时候,生成了一个 弱引用的指针 指向 self的person2变量。在block初始化的时候,把弱引用指针指向的内容地址 传递给了block成员
__weak typeof (self-&_person2) _weakPerson2;
block结构体内部通过 成员 _weakPerson2 直接弱引用了外部变量 person2的内容地址。这时候如果把person2指针指向另外一块内存地址,那么肯定是同步不到block内部的,这个和 & 大同小异。
声明&__weak&typeof(self) _weakSelf= &这样block内部 生成一个成员 ,会对self弱引用,对于值类型、引用类型都可以修改,并且修改指针指向都可以同步到任何地方。
声明&__weak&typeof(_person2) _weakPerson2=_person2; &针对某个具体的成员变量使用weak修饰符,这样可以避免循环引用,并且不能再block内部修改_weakPerson2。规则如下:
对值类型的修改,如果block初始化后,对值类型修改,无法同步到block内部。
对于引用类型的修改,如果block初始化后,修改指针指向,即指向另外一块内存,这样也是无法同步到block内部
对于引用类型的修改,如果block初始化后,对指针指向的内存进行修改,即NSMutableArray add 、remove操作,这样是可以用同步到block内部。
【编辑推荐】【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条热点热点热点热点
24H热文一周话题本月最赞
讲师:30976人学习过
讲师:218421人学习过
讲师:228052人学习过
精选博文论坛热帖下载排行
Visual C++ 6.0是Microsoft公司的Visual Studio开发组件中最强大的编程工具,利用它可以开发出高性能的应用程序。本书由浅入深,从基础到实...
订阅51CTO邮刊

我要回帖

更多关于 存储过程 临时变量 的文章

 

随机推荐