OpenHarmony开发者论坛
标题:
lazyforeach快速修改数据的时候崩溃
[打印本页]
作者:
chinabosh
时间:
2024-6-13 16:14
标题:
lazyforeach快速修改数据的时候崩溃
[md]### 【问题描述】
1. 介绍问题现象和发生的背景
应用需要快速显示一些数据
2. 相关的代码(请勿使用截图)
```
export class DataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private origin: string[]
private dataChange: () => void
constructor(data: string[]) {
this.origin = data
}
totalCount(): number {
return this.origin.length - 1
}
getData(index: number): any {
return this.origin[index]
}
onDataChange(listener: () => void) {
this.dataChange = listener
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
this.dataChange()
}
// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
this.dataChange()
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
this.dataChange()
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
this.dataChange()
}
// 通知LazyForEach组件将from索引和to索引处的子组件进行交换
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
this.dataChange()
}
}
this.mInputDataSource = new DataSource(this.mInputData)
setInterval(() => {
let data = Date.now().toString()
if (this.mInputData.length == 100) {
this.mInputData.pop()
this.mInputDataSource.notifyDataDelete(this.mInputData.length)
}
this.mInputData.unshift(data)
this.mInputDataSource.notifyDataAdd(0)
this.mInputDataSource.notifyDataReload()
}, 50)
List({ scroller: this.scroller }) {
LazyForEach(this.inputData, (item: string, index: number) => {
ListItem() {
Text(item)
.fontSize(16)
.fontColor(Color.White)
}.padding({ top: 5, bottom: 5 })
.reuseId('input list')
}, (item: string, index: number) => {
return item + index.toString()
})
}.attributeModifier(new SettingListAttribute())
.padding(20)
.layoutWeight(1)
.cachedCount(10)
```
3. 运行结果、错误截图
![image.png](
https://forums-obs.openharmony.c ... knlm3nhvmymfykx.png
"image.png")
![image.png](
https://forums-obs.openharmony.c ... xxqw0lllcqcslus.png
"image.png")
4. 我尝试过的解决方法和结果
尝试过降低更新数据频率,但是只是让崩溃来的晚一些
5. 我想要达到的结果
不崩溃
### 【运行环境】
硬件:rk3588
ROM版本:OpenHarmony 4.1.7.5
DevEvoStudio版本:4.1.3.501
SDK版本:11(full-sdk)
[/md]
作者:
chinabosh
时间:
2024-6-14 10:31
经过排查发现,不是lazyforeach的问题!!!
是其他地方错误使用了napi_create_external_arraybuffer,如下:
napi_finalize finalize_cb;
if (napi_ok !=
napi_create_external_arraybuffer(
env, buffer_data, mDataSize, finalize_cb, nullptr, &ret)) {
LOGE("ArraybufferType", "napi_create_external_arraybuffer failed");
return nullptr;
}
复制代码
按照我的推测:lazyforeach在快速更新列表的时候,会较快的触发内存回收的操作,而napi_create_external_arraybuffer这里的finalize_cb没有执行内存回收操作,导致data成野指针,从而导致内存回收时崩溃!!!
正确使用napi_create_external_arraybuffer如下
if (napi_ok !=
napi_create_external_arraybuffer(
env, buffer_data, mDataSize, [](napi_env env, void *data, void *hint) { free(data); }, nullptr, &ret)) {
LOGE("ArraybufferType", "napi_create_external_arraybuffer failed");
return nullptr;
}
复制代码
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5