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

网站建设需要的技术路线个体工商户网上年检

网站建设需要的技术路线,个体工商户网上年检,购物网站开发需求分析,葫芦岛长城建设公司网站关于OC中的block作为属性时,为什么要要用copy修饰 property (nonatomic, copy) void (^completionBlock)(void);很多文章包括AI都会给出类似结论 Block 默认分配在栈上,如果没有 copy,当方法退出后,Block 会被销毁。使用 copy 修…

关于OC中的block作为属性时,为什么要要用copy修饰

@property (nonatomic, copy) void (^completionBlock)(void);

很多文章包括AI都会给出类似结论

  • Block 默认分配在栈上,如果没有 copy,当方法退出后,Block 会被销毁。
  • 使用 copy 修饰符确保 Block 存储在堆上,避免栈上 Block 在方法返回后被销毁,确保 Block 在属性中能够正常存活和使用。
  • copy 是为了让 Block 在对象的生命周期内持久化,尤其是当 Block 需要在方法执行后继续使用时。

然而,随着技术的迭代优化,这些知识恐怕已经过时了,我们来看下面的demo

@interface ViewController ()@property (nonatomic, copy) void(^demoBolck)(void);@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.void (^tmpBlock)(void) = ^{NSLog(@"bolck called");};NSLog(@"tmpBlock %@", tmpBlock);_demoBolck = tmpBlock;NSLog(@"demoBolck %@", tmpBlock);_demoBolck();
}@end

 输出结果是这样的

tmpBlock <__NSGlobalBlock__: 0x1067cf490>

demoBolck <__NSGlobalBlock__: 0x1067cf490>

bolck called

我们看到,未引用任何外部变量的block初始化之后就是 “__NSGlobalBlock__”,在全局内存中存储,然后被当前页面的demoBlock属性引用,虽然设置了copy,但是并没有复制(内存没变)。因为他已经在全局内存了,生命周期和APP是一致的,后面随时可以调用,没有复制的必要了。我们甚至使用weak修饰这个属性也可以在后续代码中调用block:

@property (nonatomic, weak) void(^demoBolck)(void);

说到这里我们稍微展开一下,根据GPT的回答,block的存储方式有三种,原文大致如下:

  • 栈内存:用于存储局部变量和不捕获外部变量的 block。栈上的 block 会在离开作用域时自动销毁,名字:__NSStackBlock__。
  • 堆内存:用于存储捕获外部变量的 block,以及所有动态分配的对象,名字:__NSMallocBlock__。
  • 全局内存:用于存储常量和全局变量,且包括不捕获外部变量的 block,名字__NSGlobalBlock__。

有没有发现,关于栈内存和全局内存的说明是有重复的,理解起来好像是“不捕获外部变量的 block”既可以在全局内存存储也可以在栈内存存储。这里触发了他的知识盲区,反复询问也没说明白。所以我们需要继续自己做实验来验证。

既然说如果block引用了“外部变量”就会自动到堆内存,我们试一下

@interface ViewController ()@property (nonatomic, copy) void(^demoBolck)(void);@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.NSString *pageName = @"ViewController";void (^tmpBlock)(void) = ^{NSLog(@"bolck called in %@", pageName);};NSLog(@"tmpBlock %@", tmpBlock);_demoBolck = tmpBlock;NSLog(@"demoBolck %@", tmpBlock);_demoBolck();
}@end

打印结果

tmpBlock <__NSMallocBlock__: 0x7b0c000fc3c0>

demoBolck <__NSMallocBlock__: 0x7b0c000fc3c0>

bolck called in ViewController

的确,引用了外部变量之后,block直接被存储到了堆内存(名字是__NSMallocBlock__),这种情况下属性的copy依然没什么卵用,copy、strong都没有什么变化,且后续调用都正常。

还做了其他实验,简单说一下

  • 如果block仅引用了一个全局变量,block还会存在全局内存中
  • 如果block引用了当前类的一个属性,block会存在堆内存中,和局部变量一致

众多实验中,唯独没有找到block存储在栈内存中的情况,本人孤陋寡闻,望熟悉的大哥不吝赐教。

总结

1、早期的程序设计中,如果仅仅是局部作用的block,大概率是存在栈内存中的,用完就被释放掉了。然后如果被传递给了某个类来引用,需要开发者自己通过设置属性为“copy”类型实现复制到堆内存中,以便启用引用计数来管理其生命周期,所以大家都用copy来修饰block属性。

2、现阶段的环境下(我用的Xcode Version 16.2 (16C5032a),iOS18.1,模拟器),苹果做了优化。直接根据block是否引用变量,以及所引用的变量的生命周期来控制block的存储位置,和我们给的属性修饰(copy、strong)没关系了。

为什么这么做呢?我们使用block的时候,大多数情况不会在当前作用域创建并直接调用,也就是大概率是将来的某个时候回调,那他就不是临时的,就会和我们的一些变量关联起来,需要一起管理其生命周期。如果还是老逻辑,那大概率都会从栈中复制到堆,折腾一次,优化概率远效率浪费的概率。所以这种设计逐渐被抛弃了。我没找到官方文档,仅个人猜测。

接下来

1、低版本的iOS系统我们大概率都要支持几个的,所以当下并不一定所有的版本都启用了这个机制,具体从什么时候变的我不知道,没找到机器。所以还是推荐大家继续使用copy来修饰block属性

2、 如果大家一起探讨这个问题,就要加上版本这个变量,新版本什么样,老版本什么样

http://www.yayakq.cn/news/89841/

相关文章:

  • 网站建设图片教程怎样在百度上做免费推广
  • 龙泉网站开发怎么在网站做推广
  • 如何设计公司官网站广州 网站 建设 制作
  • 企业管理软件免费版seo 优化技术难度大吗
  • 不会编程能做网站吗北京网站排行榜
  • 个人网站名字取名怎么做经营一个小型app多少钱
  • 公园网站建设方案做服装商城网站
  • 网站建设与规划试卷wordpress添加账户编辑是什么意思
  • 东莞市网站建设服务机构福州网站seo推广优化
  • 汽车网站建设背景定制开发app费用
  • flash网站建设技术是什么有没有专门做教程的网站
  • 淮南 小学网站建设wordpress评论点赞怎么实现
  • 佛山市南海区城乡建设局网站同一个服务器的网站做友情链接
  • wordpress做过的大型网站网站跟客户端推广怎么做
  • 易企秀可以做网站吗怎么做网页反向链接
  • 重庆电脑网站建设wordpress编辑慢
  • 网站建设 武讯科技租号网站开发
  • 家居企业网站建设新闻wordpress 视差效果
  • 网站地图的重要性游戏制作专业
  • 姜堰网站建设安徽省工程信息网官网
  • 怎么查看网站提交百度的度汽车网站开发
  • php购物网站开发开发多久中文wordpress
  • 新闻类的手机网站怎么做上海龙腾vs山东鲁能
  • 好f123网站微机做网站的软件
  • 做网站用html还是php东莞seo全网营销
  • 青县网站建设咨询福州外贸网站建设推广
  • 描述出你要建设网站的主题怎样开通app软件
  • WordPress pdo mysql北京公交yy优化
  • 哪一个网站可以做专利检索报告服装设计学院
  • wordpress主题制作全过程(三):html静态模板制作wordpress seo 自定义结构