fix(android): FragmentClass memory leak (#9983)

* chore: resilience to create/destroy flow around actionItems

Co-authored-by: Nathan Walker <walkerrunpdx@gmail.com>
This commit is contained in:
Douglas Machado
2022-08-02 13:00:18 -03:00
committed by GitHub
parent 54d300666a
commit 0548aaf8da
4 changed files with 24 additions and 12 deletions

View File

@ -25,6 +25,10 @@ export class ActionBarBase extends View implements ActionBarDefinition {
get navigationButton(): NavigationButton { get navigationButton(): NavigationButton {
return this._navigationButton; return this._navigationButton;
} }
disposeNativeView() {
this._actionItems = null;
super.disposeNativeView();
}
set navigationButton(value: NavigationButton) { set navigationButton(value: NavigationButton) {
if (this._navigationButton !== value) { if (this._navigationButton !== value) {
if (this._navigationButton) { if (this._navigationButton) {
@ -114,7 +118,7 @@ export class ActionBarBase extends View implements ActionBarDefinition {
get _childrenCount(): number { get _childrenCount(): number {
let actionViewsCount = 0; let actionViewsCount = 0;
this._actionItems.getItems().forEach((actionItem) => { this._actionItems?.getItems().forEach((actionItem) => {
if (actionItem.actionView) { if (actionItem.actionView) {
actionViewsCount++; actionViewsCount++;
} }
@ -140,7 +144,7 @@ export class ActionBarBase extends View implements ActionBarDefinition {
public _addArrayFromBuilder(name: string, value: Array<any>) { public _addArrayFromBuilder(name: string, value: Array<any>) {
if (name === 'actionItems') { if (name === 'actionItems') {
this.actionItems.setItems(value); this.actionItems?.setItems(value);
} }
} }
@ -162,13 +166,13 @@ export class ActionBarBase extends View implements ActionBarDefinition {
callback(navigationButton); callback(navigationButton);
} }
this.actionItems.getItems().forEach((actionItem) => { this.actionItems?.getItems().forEach((actionItem) => {
callback(actionItem); callback(actionItem);
}); });
} }
public _isEmpty(): boolean { public _isEmpty(): boolean {
if (this.title || this.titleView || (this.android && this.android.icon) || this.navigationButton || this.actionItems.getItems().length > 0) { if (this.title || this.titleView || (this.android && this.android.icon) || this.navigationButton || this.actionItems?.getItems().length > 0) {
return false; return false;
} }

View File

@ -164,7 +164,7 @@ export class ActionBar extends ActionBarBase {
if (value instanceof NavigationButton) { if (value instanceof NavigationButton) {
this.navigationButton = value; this.navigationButton = value;
} else if (value instanceof ActionItem) { } else if (value instanceof ActionItem) {
this.actionItems.addItem(value); this.actionItems?.addItem(value);
} else if (value instanceof View) { } else if (value instanceof View) {
this.titleView = value; this.titleView = value;
} }
@ -257,7 +257,7 @@ export class ActionBar extends ActionBarBase {
// Find item with the right ID; // Find item with the right ID;
let menuItem: ActionItem = undefined; let menuItem: ActionItem = undefined;
const items = this.actionItems.getItems(); const items = this.actionItems?.getItems() ?? [];
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
if ((<ActionItem>items[i])._getItemId() === itemId) { if ((<ActionItem>items[i])._getItemId() === itemId) {
menuItem = <ActionItem>items[i]; menuItem = <ActionItem>items[i];
@ -352,7 +352,7 @@ export class ActionBar extends ActionBarBase {
public _addActionItems() { public _addActionItems() {
const menu = this.nativeViewProtected.getMenu(); const menu = this.nativeViewProtected.getMenu();
const items = this.actionItems.getVisibleItems(); const items = this.actionItems?.getVisibleItems() ?? [];
menu.clear(); menu.clear();
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {

View File

@ -148,7 +148,7 @@ export class ActionBar extends ActionBarBase {
if (value instanceof NavigationButton) { if (value instanceof NavigationButton) {
this.navigationButton = value; this.navigationButton = value;
} else if (value instanceof ActionItem) { } else if (value instanceof ActionItem) {
this.actionItems.addItem(value); this.actionItems?.addItem(value);
} else if (value instanceof View) { } else if (value instanceof View) {
this.titleView = value; this.titleView = value;
} }
@ -290,7 +290,7 @@ export class ActionBar extends ActionBarBase {
} }
private populateMenuItems(navigationItem: UINavigationItem) { private populateMenuItems(navigationItem: UINavigationItem) {
const items = this.actionItems.getVisibleItems(); const items = this.actionItems?.getVisibleItems() ?? [];
const leftBarItems = NSMutableArray.new(); const leftBarItems = NSMutableArray.new();
const rightBarItems = NSMutableArray.new(); const rightBarItems = NSMutableArray.new();
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
@ -449,7 +449,7 @@ export class ActionBar extends ActionBarBase {
View.measureChild(this, this.titleView, UNSPECIFIED, UNSPECIFIED); View.measureChild(this, this.titleView, UNSPECIFIED, UNSPECIFIED);
} }
this.actionItems.getItems().forEach((actionItem) => { this.actionItems?.getItems().forEach((actionItem) => {
const actionView = actionItem.actionView; const actionView = actionItem.actionView;
if (actionView) { if (actionView) {
View.measureChild(this, actionView, UNSPECIFIED, UNSPECIFIED); View.measureChild(this, actionView, UNSPECIFIED, UNSPECIFIED);
@ -473,7 +473,7 @@ export class ActionBar extends ActionBarBase {
} }
} }
this.actionItems.getItems().forEach((actionItem) => { this.actionItems?.getItems().forEach((actionItem) => {
const actionView = actionItem.actionView; const actionView = actionItem.actionView;
if (actionView && actionView.ios) { if (actionView && actionView.ios) {
const measuredWidth = actionView.getMeasuredWidth(); const measuredWidth = actionView.getMeasuredWidth();

View File

@ -324,7 +324,15 @@ export class View extends ViewCommon {
constructor() { constructor() {
super(); super();
this.on(View.loadedEvent, () => setupAccessibleView(this)); const weakRef = new WeakRef(this);
const handler = () => {
const owner = weakRef.get();
if (owner) {
setupAccessibleView(owner);
owner.off(View.loadedEvent, handler);
}
};
this.on(View.loadedEvent, handler);
} }
// TODO: Implement unobserve that detach the touchListener. // TODO: Implement unobserve that detach the touchListener.