react-native time定时器 防止内存泄露的注意点

timereact-native提供的一个定时器,在实际使用中,经常会有使用不对,造成内存泄露的情况。很多React Native应用发生致命错误(闪退)是与计时器有关。具体来说,是在某个组件被卸载(unmount)之后,计时器却仍然在运行。

防止出问题的办法也很简单,在unmount的时候,增加卸载定时器的操作:

componentDidMount() {
    this.timer = setTimeout(
      () => { console.log('把一个定时器的引用挂在this上'); },
      500
    );
  }

componentWillUnmount() {
    // 请注意Un"m"ount的m是小写
    // 如果存在this.timer,则使用clearTimeout清空。
    // 如果你使用多个timer,那么用多个变量,或者用个数组来保存引用,然后逐个clear
    this.timer && clearTimeout(this.timer);
  }

这里的timer是在DidMount中赋值的,如果是多次赋值呢?比如:

export default class test extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Button title={'click5000'} onPress={this.alertInfo.bind(this,5000)} />
        <Button title={'click2000'} onPress={this.alertInfo.bind(this,2000)} />
        <Button title={'clean timer'} onPress={this.cleanTimer.bind(this)} />
      </View>
    );
  }

  alertInfo(time){
      this.timer = setTimeout(
          ()=>{
            alert('hah');
          },
          time,
      );
  }

  cleanTimer(){
    this.timer && clearTimeout(this.timer);
    console.log('timer cleared')
  }
}


AppRegistry.registerComponent('test', () => test);

这里要介绍下setTimeout的返回值,我们打断点可以看到,this.timer是一个number。根据stack上面的其他网友的回答what-does-settimeout-return,setTimer会返回一个id,代表你已经向js的runtime系统中成功注册了一个定时器任务,这个id就是系统返回的id。

那如果是需要多次赋值,就一定要先将time clear掉,然后再赋值,或者使用多个参数来标志,否则之后就找不到上次的id,也就没办法clear了,同样可能造成内存泄露的情况。

例子如下:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button
} from 'react-native';

export default class test extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Button title={'click5000'} onPress={this.alertInfo.bind(this,5000)} />
        <Button title={'click2000'} onPress={this.alertInfo.bind(this,2000)} />
        <Button title={'clean timer'} onPress={this.cleanTimer.bind(this)} />
      </View>
    );
  }

  alertInfo(time){
      this.timer = setTimeout(
          ()=>{
            alert('hah');
          },
          time,
      );
  }

  cleanTimer(){
    this.timer && clearTimeout(this.timer);
    console.log('timer cleared')
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('test', () => test);

这里的timer多次赋值,虽然前面的值被后面的覆盖,但是前面的time仍然会起效果,如果不想前面的time work,需要clear掉,然后再赋值。

代码如下:

alertInfo(time){
        this.timer && clearTimeout(this.timer);
      this.timer = setTimeout(
          ()=>{
            alert('hah');
          },
          time,
      );
  }

综上,使用time的注意点:

  1. 记得unmount的时候,clear
  2. 多个timer要使用多个变量或者数组
  3. 多次赋值,记得把之前的值clear掉
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值