Обычно для использования AsyncStorage вы сначала импортируете его в начало файла, в документации сказано, что вы должны импортировать его следующим образом:
import { AsyncStorage } from 'react-native';
Что вы можете увидеть здесь https://facebook.github.io/react-native/docs/asyncstorage
Очевидно, вам следует удалить предыдущий оператор импорта
import { AsyncStorage } from 'AsyncStorage';
[ 1135], если оставить его, вызовет конфликт имен.
Сохранение в AsyncStorage - асинхронная задача, поэтому вы должны использовать функцию async/await
, что означает, что вы должны обновить свою функцию storeData()
. Вы можете посмотреть документацию https://facebook.github.io/react-native/docs/asyncstorage , чтобы узнать, как это сделать.
storeData = async () => {
const {a} = this.state;
let mynum = a;
try {
await AsyncStorage.setItem('array', mynum)
Alert("Saved");
} catch (err) {
console.warn(err);
}
}
Далее выглядит, что вы можете оказаться в состоянии гонки, когда вы устанавливаете состояние. SetState требуется время, чтобы установить состояние элемента. Поэтому, когда вы звоните
this.setState({ b: this.state.a });
, состояние, возможно, фактически не было установлено к тому времени, когда вы звоните
this.storeData();
, ведущему к неверное значение хранится в AsyncStorage.
Чтобы преодолеть это, есть несколько способов справиться с этим
В этой статье довольно подробно рассказывается об использовании setState с обратным вызовом https://medium.learnreact.com/setstate- принимает-a-callback-1f71ad5d2296 , однако вы можете изменить свой onPressButton
на что-то вроде этого
onPressButton = () => {
if (this.state.a == this.state.aa) {
this.setState({ b: this.state.a }, async () => { await this.storeData(); });
} else {
Alert("Try Again");
}
}
Это будет гарантировать, что this.storeData()
не будет работать, пока состояние не будет обновлено.
Для этого требуется рефакторинг функции storeData()
для получения параметра
storeData = async (mynum) => {
try {
await AsyncStorage.setItem('array',mynum)
Alert("Saved");
} catch (err) {
console.warn(err);
}
}
Теперь, чтобы использовать эту функцию, мы должны обновить your onPressButton
, обратите внимание, что мы передаем значение, которое мы хотим сохранить, в storeData
, что означает, что нам больше не нужно обращаться к нему из состояния внутри storeData
onPressButton = async () => {
if (this.state.a == this.state.aa) {
this.setState({ b: this.state.a });
await this.storeData(this.state.a);
} else {
Alert("Try Again");
}
}
Это также асинхронная задача и требует async/await
. Чтобы получить строку, которую вы сохранили, все, что вам нужно сделать, это передать правильный ключ в функцию retrieveData
retrieveData = async (key) => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
// We have data!!
console.log(value);
// do something with the value
}
} catch (error) {
// Error retrieving data
}
}
Первая вещь, которая приходит на ум для меня:
verts = [None]*1000
, Но необходимо ли действительно предварительно инициализировать его?
Вы могли сделать это:
verts = list(xrange(1000))
, Который дал бы Вам список 1 000 элементов в размере и который, оказывается, инициализируется со значениями от 0-999. Как list
делает __len__
сначала для калибровки нового списка, это должно быть довольно эффективно.
Необходимо рассмотреть использование dict
тип вместо предварительно инициализированного списка. Стоимость поиска по словарю является маленькой и сопоставимой со стоимостью доступа к произвольному элементу списка.
И при использовании отображения Вас может записать:
aDict = {}
aDict[100] = fetchElement()
putElement(fetchElement(), fetchPosition(), aDict)
И эти putElement
функция может сохранить объект в любом данном положении. И если необходимо проверить, содержит ли набор элемент в данном индексе, это - больше Pythonic для записи:
if anIndex in aDict:
print "cool!"
, Чем:
if not myList[anIndex] is None:
print "cool!"
, Так как последний предполагает, что никакой реальный элемент в Вашем наборе может быть None
. И если это происходит - Ваш код неправильно себя ведет.
И если Вам отчаянно нужны производительность и вот почему Вы пытаетесь предварительно инициализировать свои переменные, и написать самый быстрый возможный код - изменяют Ваш язык. Самый быстрый код не может быть написан в Python. Необходимо попробовать C вместо этого и обертки реализации для вызова предварительно инициализированного и предварительного скомпилированного кода из Python.
Не зная больше о проблемной области, трудно ответить на Ваш вопрос. Если Вы не уверены, что необходимо сделать что-то больше, pythonic способ инициализировать список:
verts = []
Вы на самом деле наблюдение проблемы производительности? Если так, каково узкое место производительности? Не пытайтесь решить проблему, которую Вы не имеете. Вероятно, что стоимость производительности для динамичного заполнения массива к 1 000 элементов абсолютно не важна к программе, которую Вы действительно пытаетесь записать.
класс массива полезен, если вещи в Вашем списке всегда будут определенным примитивным типом фиксированной длины (например, символ, интервал, плавание). Но, это не требует предварительной инициализации также.
Не совсем уверен, почему всем так трудно тебе хотеть для этого - есть несколько сценариев, в которых вам нужен инициализированный список фиксированного размера. И вы правильно пришли к выводу, что в этих случаях можно использовать массивы.
import array
verts=array.array('i',(0,)*1000)
Для не питонистов термин (0,) * 1000
создает кортеж, содержащий 1000 нулей. Запятая заставляет python распознавать (0)
как кортеж,