首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

用null条件运算符调用事件处理程序

有了null条件运算符之后,可以改用更为清晰的写法来实现: 这段代码采用null条件运算符(也就是?.)安全地调用事件处理程序。...该运算符首先判断其左侧的内容,如果发现这个值不是null,那就执行右侧的内容。反之,若为null,则跳过该语句,直接执行下一条语句。 从语义上来看,这与早前的if结构类似,但区别在于?....每定义一种委托或事件,编译器就会为此生成类型安全的Invoke()方法,这意味着,通过调用Invoke方法来触发事件,其效果与早前那种写法是完全相同的。...如果你在触发事件的时候头一次碰到NullReferenceException问题,然后上网求助,那么会搜索到很多推荐旧式写法的文章,那些经验是根据十几年前的情况而总结的。...以后在触发事件的时候,都应该采用这种写法。

47010

使用null条件运算符调用事件处理程序

如果存在多个线程都要检测并调用同一个事件,这些线程之间又存在争夺的问题,会出现什么情况? 针对上面这两个问题,在 C# 6.0 中新增的 null 条件运算符就可以解决这个问题。...,这时就会出现 NullReferenceException 问题,在 C#6.0 出来之前如果要解决这个问题我们需要在每次触发前都要去判断以下事件处理程序是否为 null: //C#6.0以前的处理方式...注意我这里说的时绝大部分情况,还有一种特殊的情况会出现前面所提的问题,比如 A 线程在执行完 if 语句后发现 Updated 并不等于空,这时在 A 线程还没开始执行 Updated(this,count...) 语句时 B 线程将事件处理程序的订阅解除了,那么在 A 线程执行到 Updated(this,count) 语句时事件处理程序已经为 null 了,这样仍然会出现 NullReferenceException...Invoke(this.count); } } 这段代码采用了 null 条件运算符安全的调用了事件处理程序,它首先会判断 ?

61420
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Android开发:详解Handler的内存泄露

    在Java里,非静态内部类和匿名类都会潜在引用它们所属的外部类 在了解到上述两条后,从上面的代码中可以知道: 在发送的延迟空消息(EmptyMessageDelayed)后、消息处理被前,该消息会一直保存在主线程的消息队列里持续...这条引用关系会一直保持直到消息得到处理,从而,这阻止了MainActivity被垃圾回收器(GC)回收,同时造成应用程序的内存泄漏,如下图: ? 3....从上面分析,内存泄露的原因是: 当Activity结束生命周期时,Handler里的Message可能还没处理完,从而导致一系列的引用关系。...解决方案:当Activity结束生命周期时(调用onDestroy()方法),同时清除消息队列里的所有回调消息(调用removeCallbacksAndMessages(null)) 代码如下: @Override...(null); } 经过上述两个解决方案,在Handler里的内存泄露问题就不会再出现了!

    1.1K20

    重谈Handler的内存泄漏

    Handler 的内存泄漏问题 在多线程操作中,handler会使用的非常多,但是每次使用handler你有没有考虑内存泄漏的问题。...首先来说下什么是内存泄漏 内存泄漏(Memory Leak):指的是程序已经动态分配的堆内存由于某种原因程序未释放或者无法释放,造成系统资源浪费,会造成程序运行缓慢甚至系统崩溃等严重后果。...如果此时activity要退出了,想要调用destroy销毁,但是此时Looper正在处理消息,Looper的生命周期明显比activity长,这将使得activity无法被GC回收,最终造成内存泄漏。...,清空消息队列 只需在Activity的onDestroy()方法中调用mHandler.removeCallbacksAndMessages(null);就行了。...=null){         handler.removeCallbacksAndMessages(null);         handler = null;     } }

    1.2K20

    Android Handler,Looper 与 MessageQueue 使用与分析

    实现消息驱动有几个要素 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取出消息后要对消息进行处理:Handler...发送消息 通过Looper.prepare初始化好消息队列后就可以调用Looper.loop进入消息循环了,然后我们就可以向消息队列发送消息, 消息循环就会取出消息进行处理,在看消息处理之前,先看一下消息是怎么被添加到消息队列的...在一个线程中运行的消息循环。线程默认情况下是没有与之管理的消息循环的。 要创建一个消息循环,在线程中调用prepare,然后调用loop。即开始处理消息,直到循环停止。...return; } 调用looper的quit方法,实际上调用了mQueue.quit(false)。消息队列退出后,looper的loop死循环也被退出了。...结束后要调用退出方法quit() public static void loop() 准备主线程Looper。Android环境会创建主线程Looper,开发者不应该自己调用这个方法。

    77320

    Android 进阶解密笔记-热修复

    如果此时activity要退出了,想要调用destroy销毁,但是此时Looper正在处理消息,Looper的生命周期明显比activity长,这将使得activity无法被GC回收,最终造成内存泄漏。...,清空消息队列 只需在Activity的onDestroy()方法中调用mHandler.removeCallbacksAndMessages(null);就行了。...=null){     handler.removeCallbacksAndMessages(null);     handler = null; } } 线程造成的内存泄漏 线程造成的内部泄漏以AsyncTask...,可能还没处理结束MainActivity就执行了退出操作,这时候线程的生命周期比activity长,又AsyncTask依然持有对MainActivity的引用,最后导致MainActivity无法被...比如:BroadcastReceiver,ContentObserver,FileObserver,Cursor,Callback,EventBus等在 Activity onDestroy 或者某类生命周期结束之后一定要

    39220

    Android 内存泄漏

    如果此时activity要退出了,想要调用destroy销毁,但是此时Looper正在处理消息,Looper的生命周期明显比activity长,这将使得activity无法被GC回收,最终造成内存泄漏。...,清空消息队列 只需在Activity的onDestroy()方法中调用mHandler.removeCallbacksAndMessages(null);就行了。...=null){     handler.removeCallbacksAndMessages(null);     handler = null; } } 线程造成的内存泄漏 线程造成的内部泄漏以AsyncTask...,可能还没处理结束MainActivity就执行了退出操作,这时候线程的生命周期比activity长,又AsyncTask依然持有对MainActivity的引用,最后导致MainActivity无法被...比如:BroadcastReceiver,ContentObserver,FileObserver,Cursor,Callback,EventBus等在 Activity onDestroy 或者某类生命周期结束之后一定要

    1.9K30

    Android异步通信:你了解Handler内存泄露吗?

    原因讲解 2.1 储备知识 主线程的Looper对象的生命周期 = 该应用程序的生命周期 在Java中,非静态内部类 & 匿名内部类都默认持有 外部类的引用 2.2 泄露原因描述 从上述示例代码可知:...解决方案1:静态内部类 原理:静态内部类不默认持有外部类的引用,从而使得 “未被处理 / 正处理的消息 -> Handler实例 -> 外部类” 的引用关系 不存在。...与 外部类的生命周期 同步 具体方案:当 外部类(此处以Activity为例) 结束生命周期时(此时系统会调用onDestroy()),清除 Handler消息队列里的所有消息(调用removeCallbacksAndMessages...(null)) 具体代码 @Override protected void onDestroy() { super.onDestroy(); mHandler.removeCallbacksAndMessages...(null); // 外部类Activity生命周期结束时,同时清空消息队列 & 结束Handler生命周期 } 使用建议 为了保证Handler中消息队列中的所有消息都能被执行

    66630

    Android 内存泄露简介、典型情景及检测解决

    = null) { // doSomething } } } 我们知道在handler.sendMessage(msg)时...使用WeakReference保证当 activity销毁后,不耽误gc回收activity占用的内存空间,同时在没被销毁前,可以引用activity。...管它正确错误都让它正确 通过上面的分析,可以得出结论:Handler造成内存泄露时,是因为MessageQueue中还有待处理的Message,那我们在Activity#onDestroy()中移除所有的消息不完事了嘛...Singleton(context); } } } return instance; } } 错误之处 在调用...在不需要的时候应该及时关闭它们,收回所占的内存空间。 Bitmap不用就recycle掉。注意调用recycle后并不意味着立马recycle,只是告诉虚拟机:小子,该干活咯!

    79380

    android学习笔记----Handler的使用、内存泄漏、源码分析等一系列问题

    返回false不拦截。当然如果不传这个接口的实现对象和false一样,不拦截,因为mCallback是null,进不了判断条件。...还是会处理消息,这些处理有必要? 正常Activitiy finish后,已经没有必要对消息处理,那需要怎么做呢?...比如在Handler把消息处理完了后,但是页面销毁了,这个时候可能Handler会更新UI,但是比如TextView、ImageView之类的资源引用不见了,就会抛出异常。...(null); } 这样就可以了,总结3步 ①改为handler静态内部类 ②加上弱引用 ③处理onDestroy()时removeCallbacksAndMessages(null) 某Demo...对于上面的代码,用户在关闭Activity之后,就算后台线程还没结束,但由于仅有一条来自Handler的弱引用指向Activity,所以GC仍然会在检查的时候把Activity回收掉。

    60610

    Android-强,软,弱,虚引用

    } 使用软引用引用的对象只有在程序发生oom异常前才会回收,也就是说如果内存充足永远不会被回收,只有在内存不足时才会回收,很好的避免oom,适合做缓存。...当我们调用当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。...; //调用gc回收     System.gc(); Log.e(TAG,"softReferenceMethod:----------- "+str); } 实战: 大家在项目中都经常使用...Activity结束后,Activity对象并不能够被gc回收,因而出现内存泄漏。...所以我们把MyHandller定义为静态内部类避免引用Activity,但这样的问题是:之前可以直接使用Activity中的方法,现在不持有外部Activity的引用,也就没办法直接通过方法名调用了。

    48110

    Android性能优化——之防止内存泄露

    首先是在Activity中声明静态变量或者静态方法或者静态控件 静态变量或者方法是放在静态数据区的,也就是在程序运行的过程中,只要加载过这个类之后,静态的变量或者方法,就一直会在静态数据区存在,不会释放资源...或者某类的生命周期结束后,一定要unregister掉,否则这个Activity会一直被system强引用,不会被内存回收。...属性动画导致内存泄露 例如代码中设置了属性动画(ObjectAnimator),在Activity中启动了动画,但是在销毁的时候,没有调用cancle方法,虽然我们看不到动画了,但是这个动画依然会不断地播放下去...如果用户在网络请求中关闭了Activity,正常情况下,Activity不再被使用,因该会被Gc回收掉,但是,由于该线程未执行完,而该线程持有的Handler的引用,就导致Activity无法被回收(直到网络请求结束...可以在Activity结束后,关闭线程,如果你的Handler是被delay的Message持有了引用,那么调用void removeCallbacksAndMessages(null)方法来移除消息队列

    74410

    Android Handler机制8之消息的取出与消息的其他操作

    因为调用disposed()方法后mPtr=0 final long ptr = mPtr; if (ptr == 0) { return null...或者msg是异步消息则退出循环,msg==null则意味着已经循环结束 } while (msg !...对于很多情况下,消息分发后的处理情况是第3种情况,即Handler.handleMessage(),一般地往往是通过覆写该方法从而实现自己的业务逻辑。...第5步:删除小时后nativeWake函数,以触发nativePollOnce函数,结束等待,这个块内容请在Android Handler机制9之Native的实现中,这里就不详细描述了 四、查看消息是否存在...不要在有锁或者可能有锁的代码区域调用这个方法。 这个方法的使用场景通常是,一个后台线程必须等待Handler线程中的一个任务的完成。但是,这往往是不优雅设计才会出现的问题。

    1.5K10

    使用CountDownTimer实现倒计时

    相信大家在项目里面不少会用到倒计时操作吧,倒计时功能在我们业务开发中使用概率非常高,例如用户操作姿势错误,我们给一个提示,提示是带有倒计时的对话框,当然你会问为什么不直接用Toast呢?...2)直接通过Handler方式 这种方式跟上一种区别在于handler是在oncreate()中创建的(initView()在onCreate()方法中),activity创建的时候会调用生命周期函数完成其整个生命过程...()差不多,后面的Intent大家直接可以忽略,这个是针对业务的逻辑,然后准备工作都完成后,我们在onFinishCreateView()中通过schedule(task,0,1000)开启这个task...handler消息处理 这里就是处理消息的逻辑,首先google为了程序的健壮性和一致性为当前倒计时任务进行枷锁,大家看这段代码:final longmillisLeft=mStopTimeInFuture-SystemClock.elapsedRealtime...到此,我们介绍的几种倒计时基本结束了。

    1.5K20

    轻量级控件SnackBar使用以及源码分析

    mView这个变量,终于在showView方法中,找到了addView的足迹 final void showView() { if (mView.getParent() == null)...当view已经绘制完毕后,会给它设置一个出现的动画animateViewIn,否则会给mView设置布局变化的监听,每一次布局改变都会调用动画,并把监听设置为null,这里设置为null也是非常巧妙的,...如果不这样设置,这个监听就会一直回调。...,然后是调用mHandler的removeCallbacksAndMessages和sendMessageDelayed方法,进行消息的发送,接着我们可以看一下handler做了什么处理 mHandler...Callback我们之前说过是一个接口,我们需要找一下它的实现类,既然是在show方法中把callback传进来的,所以我们要寻找一下SnackBarManager的show方法是在哪里调用的。

    1.4K20

    Android内存泄漏终极解决篇(下)

    内存泄漏的主要问题可以分为以下几种类型: 静态变量引起的内存泄漏 非静态内部类引起的内存泄漏 资源未关闭引起的内存泄漏 二、静态变量引起的内存泄漏 在java中静态变量的生命周期是在类加载时开始,类卸载时结束...换句话说,在android中其生命周期是在进程启动时开始,进程死亡时结束。所以在程序的运行期间,如果进程没有被杀死,静态变量就会一直存在,不会被回收掉。...null : atyInstance.get(); //如果Activity被释放回收了,则不处理这些消息 if (aty == null||aty.isFinishing...退出的时候移除回调 super.onDestroy(); handler.removeCallbacksAndMessages(null); } } 四、资源未关闭引起的内存泄漏...五、总结 综上所述,内存泄漏的主要情况为上面的三大类型,最终归结为一点,就是资源在不需要的时候没有被释放掉。所以在编码的过程中要注意这些细节,提高程序的性能。

    72170
    领券