Skip to content

Commit 78b5e37

Browse files
committed
fix: handle gc protection in runtime run loop
1 parent 8b932a3 commit 78b5e37

File tree

1 file changed

+60
-23
lines changed

1 file changed

+60
-23
lines changed

NativeScript/runtime/ClassBuilder.mm

+60-23
Original file line numberDiff line numberDiff line change
@@ -268,19 +268,30 @@
268268
return retain(self, @selector(retain));
269269
}
270270
if ([self retainCount] == 1) {
271-
auto innerCache = isolateWrapper.GetCache();
272-
auto it = innerCache->Instances.find(self);
273-
if (it != innerCache->Instances.end()) {
274-
v8::Locker locker(isolate);
275-
Isolate::Scope isolate_scope(isolate);
276-
HandleScope handle_scope(isolate);
277-
Local<Value> value = it->second->Get(isolate);
278-
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
279-
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
280-
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
281-
objcWrapper->GcProtect();
271+
auto runtime = Runtime::GetRuntime(isolate);
272+
auto runtimeLoop = runtime->RuntimeLoop();
273+
void* weakSelf = (__bridge void*) self;
274+
auto gcProtect = ^() {
275+
auto innerCache = isolateWrapper.GetCache();
276+
auto it = innerCache->Instances.find((id)weakSelf);
277+
if (it != innerCache->Instances.end()) {
278+
v8::Locker locker(isolate);
279+
Isolate::Scope isolate_scope(isolate);
280+
HandleScope handle_scope(isolate);
281+
Local<Value> value = it->second->Get(isolate);
282+
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
283+
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
284+
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
285+
objcWrapper->GcProtect();
286+
}
282287
}
288+
};
289+
if(CFRunLoopGetCurrent() != runtimeLoop) {
290+
tns::ExecuteOnRunLoop(runtimeLoop, gcProtect);
291+
} else {
292+
gcProtect();
283293
}
294+
284295
}
285296

286297
return retain(self, @selector(retain));
@@ -295,18 +306,44 @@
295306
}
296307

297308
if ([self retainCount] == 2) {
298-
auto innerCache = isolateWrapper.GetCache();
299-
auto it = innerCache->Instances.find(self);
300-
if (it != innerCache->Instances.end()) {
301-
v8::Locker locker(isolate);
302-
Isolate::Scope isolate_scope(isolate);
303-
HandleScope handle_scope(isolate);
304-
if (it->second != nullptr) {
305-
Local<Value> value = it->second->Get(isolate);
306-
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
307-
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
308-
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
309-
objcWrapper->GcUnprotect();
309+
void* weakSelf = (__bridge void*) self;
310+
auto gcUnprotect = ^() {
311+
312+
313+
auto innerCache = isolateWrapper.GetCache();
314+
auto it = innerCache->Instances.find((id)weakSelf);
315+
if (it != innerCache->Instances.end()) {
316+
v8::Locker locker(isolate);
317+
Isolate::Scope isolate_scope(isolate);
318+
HandleScope handle_scope(isolate);
319+
if (it->second != nullptr) {
320+
Local<Value> value = it->second->Get(isolate);
321+
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
322+
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
323+
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
324+
objcWrapper->GcUnprotect();
325+
}
326+
}
327+
}
328+
};
329+
auto runtime = Runtime::GetRuntime(isolate);
330+
auto runtimeLoop = runtime->RuntimeLoop();
331+
if(CFRunLoopGetCurrent() != runtimeLoop) {
332+
tns::ExecuteOnRunLoop(runtimeLoop, gcUnprotect);
333+
} else {
334+
auto innerCache = isolateWrapper.GetCache();
335+
auto it = innerCache->Instances.find(self);
336+
if (it != innerCache->Instances.end()) {
337+
v8::Locker locker(isolate);
338+
Isolate::Scope isolate_scope(isolate);
339+
HandleScope handle_scope(isolate);
340+
if (it->second != nullptr) {
341+
Local<Value> value = it->second->Get(isolate);
342+
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
343+
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
344+
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
345+
objcWrapper->GcUnprotect();
346+
}
310347
}
311348
}
312349
}

0 commit comments

Comments
 (0)