react / react/react-native

Memory leak when programmatically changing 'source' prop of Image

Aperta
#12,220 21 commenti 17 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Component: Image Good first issue Platform: iOS
Lingua principale
C++
Stelle
127k
Fork
25.3k
Merge medio
1g 23h
PR unite (30g)
4

Descrizione

Description

If you use an Image component in render and use the parent component's state to manage the source prop, each time the source is changed the previous source is not deallocated. Even when the parent component is unmounted, the previous images still use memory.

imagetest_memory_leak
Reproduction

I've made a simple ImageTest project that demonstrates the bug. (IMPORTANT: run app in release mode to experience the issue)

Code:

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

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

import image0 from './images/0.png'
import image1 from './images/1.png'
import image2 from './images/2.png'
import image3 from './images/3.png'
import image4 from './images/4.png'

const images = [
  image0,
  image1,
  image2,
  image3,
  image4,
]

export default class ImageTest extends Component {
  constructor() {
    super()

    this.state = ({
      counter: 0,
    })
  }

  increment = () => {
    this.setState({
      counter: this.state.counter + 1
    })
  }

  render() {
    const imageSource = images[this.state.counter]

    return (
      <View>
        <Image
          source={imageSource}
          style={styles.image}
        />
        <TouchableHighlight onPress={this.increment} style={styles.highlight}>
          <Text style={styles.text}>NEXT IMAGE</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

const window = Dimensions.get('window')

const styles = StyleSheet.create({
  highlight: {
    backgroundColor: 'yellow',
    position: 'absolute',
    bottom: 0,
    left: 0,
  },
  text: {
    fontSize: 50,
  },
  image: {
    width: window.width,
    height: window.height,
  },
});

AppRegistry.registerComponent('ImageTest', () => ImageTest);
Solution

Presumably when the source is changed the underlying UIImage/UIImageView needs to be destroyed.

Additional Information
  • React Native version: 0.41.0
  • Platform: iOS
  • Operating System: MacOS 10.12.3 / xcode 8.2

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con la riproduzione ImageTest collegata ed eseguila in iOS release mode, modificando la source prop dell'Image component mentre osservi la memoria. Traccia la gestione nativa iOS delle modifiche a source da parte dell'Image component; il lavoro è completato quando le immagini precedenti vengono deallocate dopo le modifiche e dopo lo smontaggio del parent component.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
ios, react-native
Ambito
mobile
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.