22#include " DataWrapper.h"
33#include " Helpers.h"
44#include " Interop.h"
5- #include " Caches .h"
5+ #include " IsolateWrapper .h"
66
77using namespace tns ;
88using namespace v8 ;
99
1010@implementation ArrayAdapter {
11- Isolate* isolate_ ;
11+ IsolateWrapper* wrapper_ ;
1212 std::shared_ptr<Persistent<Value>> object_;
13- std::shared_ptr<Caches> cache_;
13+ // we're responsible for this wrapper
14+ ObjCDataWrapper* dataWrapper_;
1415}
1516
1617- (instancetype )initWithJSObject : (Local<Object>)jsObject isolate : (Isolate*)isolate {
1718 if (self) {
18- self->isolate_ = isolate;
19- self->cache_ = Caches::Get (isolate);
19+ self->wrapper_ = new IsolateWrapper (isolate);
2020 self->object_ = std::make_shared<Persistent<Value>>(isolate, jsObject);
21- self->cache_ ->Instances .emplace (self, self->object_ );
22- tns::SetValue (isolate, jsObject, new ObjCDataWrapper (self));
21+ self->wrapper_ -> GetCache () ->Instances .emplace (self, self->object_ );
22+ tns::SetValue (isolate, jsObject, (self-> dataWrapper_ = new ObjCDataWrapper (self) ));
2323 }
24-
24+
2525 return self;
2626}
2727
2828- (NSUInteger )count {
29- v8::Locker locker (self->isolate_ );
30- Isolate::Scope isolate_scope (self->isolate_ );
31- HandleScope handle_scope (self->isolate_ );
32-
33- Local<Object> object = self->object_ ->Get (self->isolate_ ).As <Object>();
29+ auto isolate = wrapper_->Isolate ();
30+ if (!wrapper_->IsValid ()) {
31+ return 0 ;
32+ }
33+ v8::Locker locker (isolate);
34+ Isolate::Scope isolate_scope (isolate);
35+ HandleScope handle_scope (isolate);
36+
37+ Local<Object> object = self->object_ ->Get (isolate).As <Object>();
3438 if (object->IsArray ()) {
3539 uint32_t length = object.As <v8::Array>()->Length ();
3640 return length;
3741 }
38-
39- Local<Context> context = self-> cache_ ->GetContext ();
42+
43+ Local<Context> context = wrapper_-> GetCache () ->GetContext ();
4044 Local<v8::Array> propertyNames;
4145 bool success = object->GetPropertyNames (context).ToLocal (&propertyNames);
42- tns::Assert (success, self-> isolate_ );
46+ tns::Assert (success, isolate );
4347 uint32_t length = propertyNames->Length ();
4448 return length;
4549}
4650
4751- (id )objectAtIndex : (NSUInteger )index {
48- v8::Locker locker (self->isolate_ );
49- Isolate::Scope isolate_scope (self->isolate_ );
50- HandleScope handle_scope (self->isolate_ );
51-
52+ auto isolate = wrapper_->Isolate ();
53+ if (!wrapper_->IsValid ()) {
54+ return nil ;
55+ }
56+ v8::Locker locker (isolate);
57+ Isolate::Scope isolate_scope (isolate);
58+ HandleScope handle_scope (isolate);
59+
5260 if (!(index < [self count ])) {
53- tns::Assert (false , self-> isolate_ );
61+ tns::Assert (false , isolate );
5462 }
55-
56- Local<Object> object = self->object_ ->Get (self-> isolate_ ).As <Object>();
57- Local<Context> context = self-> cache_ ->GetContext ();
63+
64+ Local<Object> object = self->object_ ->Get (isolate ).As <Object>();
65+ Local<Context> context = wrapper_-> GetCache () ->GetContext ();
5866 Local<Value> item;
5967 bool success = object->Get (context, (uint)index).ToLocal (&item);
60- tns::Assert (success, self-> isolate_ );
61-
68+ tns::Assert (success, isolate );
69+
6270 if (item->IsNullOrUndefined ()) {
6371 return nil ;
6472 }
@@ -68,16 +76,29 @@ - (id)objectAtIndex:(NSUInteger)index {
6876}
6977
7078- (void )dealloc {
71- self->cache_ ->Instances .erase (self);
72- Local<Value> value = self->object_ ->Get (self->isolate_ );
73- BaseDataWrapper* wrapper = tns::GetValue (self->isolate_ , value);
74- if (wrapper != nullptr ) {
75- tns::DeleteValue (self->isolate_ , value);
76- delete wrapper;
79+ if (wrapper_->IsValid ()) {
80+ auto isolate = wrapper_->Isolate ();
81+ v8::Locker locker (isolate);
82+ Isolate::Scope isolate_scope (isolate);
83+ HandleScope handle_scope (isolate);
84+ wrapper_->GetCache ()->Instances .erase (self);
85+ Local<Value> value = self->object_ ->Get (isolate);
86+ BaseDataWrapper* wrapper = tns::GetValue (isolate, value);
87+ if (wrapper != nullptr ) {
88+ tns::DeleteValue (isolate, value);
89+ // ensure we don't delete the same wrapper twice
90+ // this is just needed as a failsafe in case some other wrapper is assigned to this object
91+ if (wrapper == dataWrapper_) {
92+ dataWrapper_ = nullptr ;
93+ }
94+ delete wrapper;
95+ }
96+ self->object_ ->Reset ();
97+ }
98+ delete wrapper_;
99+ if (dataWrapper_ != nullptr ) {
100+ delete dataWrapper_;
77101 }
78- self->object_ ->Reset ();
79- self->isolate_ = nullptr ;
80- self->cache_ = nullptr ;
81102 self->object_ = nullptr ;
82103 [super dealloc ];
83104}
0 commit comments