mirror of
https://github.com/openharmony/ace_ace_engine.git
synced 2026-07-19 14:43:36 -04:00
fix the problem of LazyForEach deleted function
Signed-off-by: yan-shuifeng <yanshuifeng@huawei.com> Change-Id: I6ad038d3c8f0d9a3041cdb2904f7e4010b563f4c
This commit is contained in:
@@ -293,11 +293,15 @@ public:
|
||||
auto viewStack = ViewStackProcessor::GetInstance();
|
||||
auto multiComposed = AceType::MakeRefPtr<MultiComposedComponent>(key, "LazyForEach");
|
||||
viewStack->Push(multiComposed);
|
||||
|
||||
if (parentView_) {
|
||||
parentView_->MarkLazyForEachProcess(key);
|
||||
}
|
||||
viewStack->PushKey(key);
|
||||
itemGenFunc_->Call(JSRef<JSObject>(), 1, &result);
|
||||
viewStack->PopKey();
|
||||
|
||||
if (parentView_) {
|
||||
parentView_->ResetLazyForEachProcess();
|
||||
}
|
||||
auto component = viewStack->Finish();
|
||||
ACE_DCHECK(multiComposed == component);
|
||||
|
||||
|
||||
@@ -243,13 +243,22 @@ void JSView::DestructorCallback(JSView* view)
|
||||
void JSView::DestroyChild(JSView* parentCustomView)
|
||||
{
|
||||
LOGD("JSView::DestroyChild start");
|
||||
for (auto child : customViewChildren_) {
|
||||
for (auto&& child : customViewChildren_) {
|
||||
auto* view = child.second->Unwrap<JSView>();
|
||||
if (view != nullptr) {
|
||||
view->Destroy(this);
|
||||
}
|
||||
child.second.Reset();
|
||||
}
|
||||
customViewChildren_.clear();
|
||||
for (auto&& lazyChild : customViewChildrenWithLazy_) {
|
||||
auto* view = lazyChild.second->Unwrap<JSView>();
|
||||
if (view != nullptr) {
|
||||
view->Destroy(this);
|
||||
}
|
||||
lazyChild.second.Reset();
|
||||
}
|
||||
customViewChildrenWithLazy_.clear();
|
||||
LOGD("JSView::DestroyChild end");
|
||||
}
|
||||
|
||||
@@ -287,50 +296,64 @@ JSRef<JSObject> JSView::GetChildById(const std::string& viewId)
|
||||
ChildAccessedById(id);
|
||||
return found->second;
|
||||
}
|
||||
auto lazyItem = customViewChildrenWithLazy_.find(id);
|
||||
if (lazyItem != customViewChildrenWithLazy_.end()) {
|
||||
return lazyItem->second;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string JSView::AddChildById(const std::string& viewId, const JSRef<JSObject>& obj)
|
||||
{
|
||||
auto id = ViewStackProcessor::GetInstance()->ProcessViewId(viewId);
|
||||
customViewChildren_.emplace(id, obj);
|
||||
ChildAccessedById(id);
|
||||
JSView* jsview = nullptr;
|
||||
if (isLazyForEachProcessed_) {
|
||||
auto result = customViewChildrenWithLazy_.try_emplace(id, obj);
|
||||
if (!result.second) {
|
||||
jsview = result.first->second->Unwrap<JSView>();
|
||||
result.first->second = obj;
|
||||
}
|
||||
lazyItemGroups_[lazyItemGroupId_].emplace_back(id);
|
||||
} else {
|
||||
auto result = customViewChildren_.try_emplace(id, obj);
|
||||
if (!result.second) {
|
||||
jsview = result.first->second->Unwrap<JSView>();
|
||||
result.first->second = obj;
|
||||
}
|
||||
ChildAccessedById(id);
|
||||
}
|
||||
if (jsview != nullptr) {
|
||||
jsview->Destroy(this);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void JSView::RemoveChildGroupById(const std::string& viewId)
|
||||
{
|
||||
JAVASCRIPT_EXECUTION_SCOPE_STATIC;
|
||||
if (viewId.empty()) {
|
||||
auto removeView = customViewChildren_.find(viewId);
|
||||
if (removeView != customViewChildren_.end()) {
|
||||
LOGD("RemoveChildGroupById in lazy for each case: %{public}s", viewId.c_str());
|
||||
auto iter = lazyItemGroups_.find(viewId);
|
||||
if (iter == lazyItemGroups_.end()) {
|
||||
LOGI("can not find this groud to delete: %{public}s", viewId.c_str());
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> removedViewIds;
|
||||
for (auto&& item : iter->second) {
|
||||
auto removeView = customViewChildrenWithLazy_.find(item);
|
||||
if (removeView != customViewChildrenWithLazy_.end()) {
|
||||
auto* view = removeView->second->Unwrap<JSView>();
|
||||
if (view != nullptr) {
|
||||
view->Destroy(this);
|
||||
}
|
||||
removeView->second.Reset();
|
||||
customViewChildren_.erase(removeView);
|
||||
removedViewIds.emplace_back(item);
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto startIter = customViewChildren_.begin();
|
||||
auto endIter = customViewChildren_.end();
|
||||
std::vector<std::string> removedViewIds;
|
||||
while (startIter != endIter) {
|
||||
if (StartWith(startIter->first, viewId)) {
|
||||
removedViewIds.emplace_back(startIter->first);
|
||||
auto* view = startIter->second->Unwrap<JSView>();
|
||||
if (view != nullptr) {
|
||||
view->Destroy(this);
|
||||
}
|
||||
startIter->second.Reset();
|
||||
}
|
||||
++startIter;
|
||||
}
|
||||
|
||||
for (auto&& removeId : removedViewIds) {
|
||||
customViewChildren_.erase(removeId);
|
||||
customViewChildrenWithLazy_.erase(removeId);
|
||||
}
|
||||
lazyItemGroups_.erase(iter);
|
||||
}
|
||||
|
||||
void JSView::ChildAccessedById(const std::string& viewId)
|
||||
|
||||
@@ -114,6 +114,18 @@ public:
|
||||
jsViewFunction_->ExecuteUpdateWithValueParams(jsonData);
|
||||
}
|
||||
|
||||
void MarkLazyForEachProcess(const std::string& groudId)
|
||||
{
|
||||
isLazyForEachProcessed_ = true;
|
||||
lazyItemGroupId_ = groudId;
|
||||
}
|
||||
|
||||
void ResetLazyForEachProcess()
|
||||
{
|
||||
isLazyForEachProcessed_ = false;
|
||||
lazyItemGroupId_ = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* New CustomView child will be added to the map.
|
||||
* and it can be reterieved for recycling in next render function
|
||||
@@ -153,6 +165,8 @@ private:
|
||||
WeakPtr<OHOS::Ace::ComposedElement> element_ = nullptr;
|
||||
bool needsUpdate_ = false;
|
||||
bool isStatic_ = false;
|
||||
bool isLazyForEachProcessed_ = false;
|
||||
std::string lazyItemGroupId_;
|
||||
|
||||
RefPtr<ViewFunctions> jsViewFunction_;
|
||||
|
||||
@@ -161,6 +175,15 @@ private:
|
||||
// hold handle to the native and javascript object to keep them alive
|
||||
// until they are abandoned
|
||||
std::unordered_map<std::string, JSRef<JSObject>> customViewChildren_;
|
||||
|
||||
// hold handle to the native and javascript object to keep them alive
|
||||
// until they are abandoned used by lazyForEach
|
||||
std::unordered_map<std::string, JSRef<JSObject>> customViewChildrenWithLazy_;
|
||||
|
||||
// hold js view ids by lazy item ground.
|
||||
// until they are abandoned used by lazyForEach
|
||||
std::unordered_map<std::string, std::list<std::string>> lazyItemGroups_;
|
||||
|
||||
// a set of valid viewids on a renderfuntion excution
|
||||
// its cleared after cleaning up the abandoned child.
|
||||
std::unordered_set<std::string> lastAccessedViewIds_;
|
||||
|
||||
@@ -163,7 +163,16 @@ private:
|
||||
class LazyForEachElementProxy : public ElementProxy, public DataChangeListener {
|
||||
public:
|
||||
explicit LazyForEachElementProxy(const WeakPtr<ElementProxyHost>& host) : ElementProxy(host) {}
|
||||
~LazyForEachElementProxy() override = default;
|
||||
~LazyForEachElementProxy() override
|
||||
{
|
||||
for (auto&& item : children_) {
|
||||
auto viewId = item.second->GetId();
|
||||
if (lazyForEachComponent_) {
|
||||
lazyForEachComponent_->ReleaseChildGroupByComposedId(viewId);
|
||||
}
|
||||
}
|
||||
children_.clear();
|
||||
}
|
||||
|
||||
void Update(const RefPtr<Component>& component, size_t startIndex) override
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user