翻车了!!!一个小例子带你了解闭包。
事故现场:
场景:6个button,上方1个text。点击button,text会显示button上的数字。
代码如下:

//在unity里面赋值
public List<Button> buttons = new List<Button>();
public Text text;
void Start () {
AddFun();
}
//给6个button添加点击事件
void AddFun()
{
for (int i = 0; i < buttons.Count; i++)
{
buttons[i].onClick.AddListener(() => Fun(i + 1));
}
}
//点击事件:输出形参的值
void Fun(int i)
{
text.text = i.ToString();
print(i);
}
for循环button添加onclidk函数导致点击所有的button显示同样的莫名数字7。

事故原因:
闭包。标题那么长跟闭包有什么关系?因为上述问题会引起闭包。为什么标题中不直接写出关键字闭包?因为叫的出闭包的人基本上都会避免这个问题,这篇文章主要针对新人,那些没听过闭包的人。

事故分析:
1、什么是闭包?我也不知道哈,非科班,定义百度一下吧。

2、怎么会产生闭包?内部函数使用了外部函数的局部变量。内部函数:是我对匿名函数,lambda表达式等函数嵌套情况的称呼。如上述例子:外部函数Addfun,内部函数是lambda表达式,i是外部函数for循环中的局部变量,内部函数lambda表达式使用了i这个局部变量。

3、闭包会导致什么的结果?闭包会延长所用外部函数局部变量的生命周期,或者说是局部变量变成了全局变量。

内存分析:

通俗的讲就是局部变量i从没被释放,一直存在内存中,随着i++,值增到了6,所有button的点击函数都是传进的i+1,也就是7,为实参,所以fun函数打印的数字为7

处理办法:
重新申请内存。代码如下:

public List<Button> buttons = new List<Button>();
public Text text;
void Start () {
AddFun();
}

void AddFun()
{
for (int i = 0; i < buttons.Count; i++)
{
//重新申请的内存
int index = i;
buttons[i].onClick.AddListener(() => Fun(index + 1));
}
}
void Fun(int i)
{
text.text = i.ToString();
print(i);
}
内存分析:

通过初始化重新申请了6块内存,内块内存保存了不同的index值(index值是由i赋值而来)。虽然index变量的生命周期也被延长,但是不同的button的点击函数访问的传进参数的内存不同,因此fun函数打印的数字也就不同。

事件解决:

拓展:
其实闭包在脚本语言中非常常见,也非常有用。以lua为例,代码如下:

function OutSideFun()

local i=0
local function InsideFun()
i=i+1
print(i)
end

return InsideFun
end

local fun=OutSideFun()

fun()
fun()
fun()
那么自己可以试试输出值是多少,分析一下为什么是这样。

更多unity2018课程请直接到paws3d上查找。

Unity_新手必懂知识点的更多相关文章

  1. 干货:Java并发编程必懂知识点解析

    本文大纲 并发编程三要素 原子性 原子,即一个不可再被分割的颗粒.在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败. 有序性 程序执行的顺序按照代码的先后顺序执行.(处理器可能会 ...

  2. 十一:WEB渗透必懂知识点

    简述WEB层面上的漏洞以及类型,具体漏洞的危害等级, 如何形成以及如何发现 右边权重大于左边 CTF,SRC,红蓝对抗,实战 简要说明以上漏洞危害 简要说课以上漏洞等级划分 简要说明以上漏洞重点内容 ...

  3. [新手必备]Python 基础入门必学知识点笔记

    Python 作为近几年越来越流行的语言,吸引了大量的学员开始学习,为了方便新手小白在学习过程中,更加快捷方便的查漏补缺.根据网上各种乱七八糟的资料以及实验楼的 Python 基础内容整理了一份极度适 ...

  4. python新手必躺的5大坑

    python新手必躺的5大坑 对于Python新手来说,写代码很少考虑代码的效率和简洁性,因此容易造成代码冗长.执行慢,这些都是需要改进的地方.本文是想通过几个案列给新手一点启发,怎样写python代 ...

  5. 深度剖析HashMap的数据存储实现原理(看完必懂篇)

    深度剖析HashMap的数据存储实现原理(看完必懂篇) 具体的原理分析可以参考一下两篇文章,有透彻的分析! 参考资料: 1. https://www.jianshu.com/p/17177c12f84 ...

  6. 新手必看】Highcharts的100个基础问答

    新手必看]Highcharts的100个基础问答 2014-12-2 10:59| 发布者: Mr.Zhang| 查看: 2749| 评论: 3|来自: Highcharts中文论坛   摘要: 1. ...

  7. 必懂的webpack高级配置

    webpack高级配置 1.HTML中img标签的图片资源处理 使用时.只需要在html中正常引用图片即可.webpack就会找到对应的资源进行打包.并修改html中的引用路径 主要是将html中的i ...

  8. 必懂的wenpack优化

    webpack优化 1.production 模式打包自带优化 tree shaking tree shaking是一个术语.通常用于打包时移除js中未引用的代码(dead-code),它依赖于ES6 ...

  9. Node.js新手必须知道的4个JavaScript概念

    如果只需要知道一种编程语言就可以构建一个全栈的应用程序,是不是特别了不起?Ryan Dahl为了把这个想法成为现实,创造了node.js.Node.js是建立在Chrome强劲的V8 JavaScri ...

随机推荐

  1. GitHub学习笔记:分支管理

    GitHub对于每个开发版本都需要有一个分支,默认的分支是master往往被大家保留下来作为主分支,分支类似于进程的一个指针,往往在master这个稳定的主干版本上分出一个或多个正在开发的分支版本,开 ...

  2. vue目录结构

    构建新的项目后生成目录结构如下图: 1.build目录下: 最终发布de代码存放的位置 2.config 配置目录,包括端口号等.我们初学可以使用默认的 3.node_modules npm加载的项目 ...

  3. Hibernate Session总结

    现在我们可以在 IDEA 下新建一个 Hibernate 项目,接着上次内容这次主要总结一下 Hibernate 的 Session,及其核心方法. Session 概述 Session 接口是 Hi ...

  4. Android Zxing 转换竖屏扫描且提高识别率

    最近的一个Android需要用到扫码功能,用的是Zxing开源库.Zxing的集成就不说了,但是Zxing默认的是横屏扫码,在实际生产中并不适用,需要改为竖屏扫描. 转竖屏步骤: 1>. And ...

  5. 全面认识openstack:OpenStack架构详解

    OpenStack构架知识梳理   OpenStack既是一个社区,也是一个项目和一个开源软件,提供开放源码软件,建立公共和私有云,它提供了一个部署云的操作平台或工具集,其宗旨在于:帮助组织运行为虚拟 ...

  6. maven中pom文件配置解决资源文件的编码问题

    <build> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId& ...

  7. Spring Boot ConfigurationProperties validate

    使用@Query可以在自定义的查询方法上使用@Query来指定该方法要执行的查询语句,比如:@Query("select o from UserModel o where o.uuid=?1 ...

  8. celery学习笔记2

    1.定义: Celery是一个异步的任务队列(也叫做分布式任务队列) 2.工作结构 Celery分为3个部分 (1)worker部分负责任务的处理,即工作进程(我的理解工作进程就是你写的python代 ...

  9. 第十三章——卷积神经网络(CNN)

    卷积神经网络(Convolutional neural networks,CNNs)来源于对大脑视觉皮层的研究,并于1980s开始应用于图像识别.现如今CNN已经在复杂的视觉任务中取得了巨大成功,比如 ...

  10. 【gcd+stl】UVa1642 Magical GCD

    Description 一个长度为n的数列,选一个连续子序列,使得子序列的公约数*长度最大,求这个最大值.n<=1e5. Solution 连续子序列一般都要用滑动窗口是吧(固定r,快速计算最优 ...