Skip to content

Commit 476a44b

Browse files
Fixed SIGABRT and EXC_BAD_ACCESS crashes (fix #39)
1 parent 44e96bc commit 476a44b

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
}],
1111
"no-underscore-dangle": ["error", {
1212
"allow": [
13+
"_uid",
1314
"_sink",
1415
"_internalRoot",
1516
"_targetTextNode",

src/react-tvml/index.js

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,28 @@ const supportedEventMapping = {
5353
onHoldselect: 'holdselect',
5454
};
5555

56+
let uid = 0;
57+
58+
function getNodeId(node) {
59+
if (node) {
60+
if (node._uid == null) {
61+
/**
62+
* `console.info` is a weird workaround that prevents nodes
63+
* from the aggressive GC in tvOS 12.
64+
*
65+
* This fixes:
66+
* - ITMLKit (9): EXC_BAD_ACCESS
67+
* - ITMLKit (8): signal SIGABRT
68+
*/
69+
console.info('Preventing node from GC', node);
70+
uid += 1;
71+
node._uid = uid;
72+
}
73+
return node._uid;
74+
}
75+
return null;
76+
}
77+
5678
function isTextNode(node) {
5779
return node && node.nodeType === TEXT_NODE;
5880
}
@@ -348,13 +370,13 @@ const TVMLRenderer = ReactFiberReconciler({
348370
if (isTextNode(target) && isTextNode(child)) {
349371
if (!target._handledTextNodes) {
350372
target._handledTextNodes = [{
351-
node: target,
373+
id: getNodeId(target),
352374
value: target.nodeValue,
353375
}];
354376
}
355377

356378
target._handledTextNodes.push({
357-
node: child,
379+
id: getNodeId(child),
358380
value: child.nodeValue,
359381
});
360382

@@ -446,7 +468,8 @@ const TVMLRenderer = ReactFiberReconciler({
446468

447469
if (target) {
448470
const nodes = target._handledTextNodes;
449-
const reference = nodes.find(({ node }) => node === textInstance);
471+
const nodeId = getNodeId(textInstance);
472+
const reference = nodes.find(({ id }) => id === nodeId);
450473

451474
reference.value = newText;
452475
updateNodeValue(target);
@@ -465,13 +488,13 @@ const TVMLRenderer = ReactFiberReconciler({
465488
if (isTextNode(target) && isTextNode(child)) {
466489
if (!target._handledTextNodes) {
467490
target._handledTextNodes = [{
468-
node: target,
491+
id: getNodeId(target),
469492
value: target.nodeValue,
470493
}];
471494
}
472495

473496
target._handledTextNodes.push({
474-
node: child,
497+
id: getNodeId(child),
475498
value: child.nodeValue,
476499
});
477500

@@ -499,13 +522,13 @@ const TVMLRenderer = ReactFiberReconciler({
499522
if (isTextNode(beforeChild) && isTextNode(child)) {
500523
if (!beforeChild._handledTextNodes) {
501524
beforeChild._handledTextNodes = [{
502-
node: beforeChild,
525+
id: getNodeId(beforeChild),
503526
value: beforeChild.nodeValue,
504527
}];
505528
}
506529

507530
beforeChild._handledTextNodes.unshift({
508-
node: child,
531+
id: getNodeId(child),
509532
value: child.nodeValue,
510533
});
511534

@@ -535,14 +558,16 @@ const TVMLRenderer = ReactFiberReconciler({
535558
if (child._targetTextNode) {
536559
const target = child._targetTextNode;
537560
const nodes = target._handledTextNodes;
538-
const referenceIndex = nodes.findIndex(({ node }) => node === child);
561+
const nodeId = getNodeId(child);
562+
const referenceIndex = nodes.findIndex(({ id }) => id === nodeId);
539563

540564
nodes.splice(referenceIndex, 1);
541565
delete child._targetTextNode;
542566
updateNodeValue(target);
543567
} else if (child._handledTextNodes && child._handledTextNodes.length) {
544568
const nodes = child._handledTextNodes;
545-
const reference = nodes.find(({ node }) => node === child);
569+
const nodeId = getNodeId(child);
570+
const reference = nodes.find(({ id }) => id === nodeId);
546571

547572
reference.value = '';
548573
updateNodeValue(child);

0 commit comments

Comments
 (0)