Keep permanent flag in KotlinBase instead of requesting from the object
This works better when the object becomes invalid
This commit is contained in:
committed by
SvyatoslavScherbina
parent
185f0a3101
commit
e5e1648462
+1
-1
@@ -121,7 +121,7 @@ private fun PatchBuilder.addObjCPatches() {
|
|||||||
addPrivateCategory("NSDictionaryToKotlin")
|
addPrivateCategory("NSDictionaryToKotlin")
|
||||||
addPrivateCategory("NSEnumeratorAsAssociatedObject")
|
addPrivateCategory("NSEnumeratorAsAssociatedObject")
|
||||||
|
|
||||||
addExportedClass(objCExportNamer.kotlinAnyName, "KotlinBase", "refHolder")
|
addExportedClass(objCExportNamer.kotlinAnyName, "KotlinBase", "refHolder", "permanent")
|
||||||
|
|
||||||
addExportedClass(objCExportNamer.mutableSetName, "KotlinMutableSet", "setHolder")
|
addExportedClass(objCExportNamer.mutableSetName, "KotlinMutableSet", "setHolder")
|
||||||
addExportedClass(objCExportNamer.mutableMapName, "KotlinMutableDictionary", "mapHolder")
|
addExportedClass(objCExportNamer.mutableMapName, "KotlinMutableDictionary", "mapHolder")
|
||||||
|
|||||||
@@ -58,10 +58,6 @@ class BackRefFromAssociatedObject {
|
|||||||
template <ErrorPolicy errorPolicy>
|
template <ErrorPolicy errorPolicy>
|
||||||
ObjHeader* ref() const;
|
ObjHeader* ref() const;
|
||||||
|
|
||||||
inline bool permanent() const {
|
|
||||||
return obj_->permanent(); // Safe to query from any thread.
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ObjHeader* obj_;
|
ObjHeader* obj_;
|
||||||
ForeignRefContext context_;
|
ForeignRefContext context_;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ static void injectToRuntime();
|
|||||||
|
|
||||||
@implementation KotlinBase {
|
@implementation KotlinBase {
|
||||||
BackRefFromAssociatedObject refHolder;
|
BackRefFromAssociatedObject refHolder;
|
||||||
|
bool permanent;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(KRef)toKotlin:(KRef*)OBJ_RESULT {
|
-(KRef)toKotlin:(KRef*)OBJ_RESULT {
|
||||||
@@ -79,6 +80,8 @@ static void injectToRuntime();
|
|||||||
ObjHolder holder;
|
ObjHolder holder;
|
||||||
AllocInstanceWithAssociatedObject(typeInfo, result, holder.slot());
|
AllocInstanceWithAssociatedObject(typeInfo, result, holder.slot());
|
||||||
result->refHolder.initAndAddRef(holder.obj());
|
result->refHolder.initAndAddRef(holder.obj());
|
||||||
|
RuntimeAssert(!holder.obj()->permanent(), "dynamically allocated object is permanent");
|
||||||
|
result->permanent = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +89,7 @@ static void injectToRuntime();
|
|||||||
KotlinBase* candidate = [super allocWithZone:nil];
|
KotlinBase* candidate = [super allocWithZone:nil];
|
||||||
// TODO: should we call NSObject.init ?
|
// TODO: should we call NSObject.init ?
|
||||||
candidate->refHolder.initAndAddRef(obj);
|
candidate->refHolder.initAndAddRef(obj);
|
||||||
|
candidate->permanent = obj->permanent();
|
||||||
|
|
||||||
if (!obj->permanent()) { // TODO: permanent objects should probably be supported as custom types.
|
if (!obj->permanent()) { // TODO: permanent objects should probably be supported as custom types.
|
||||||
if (!obj->container()->shareable()) {
|
if (!obj->container()->shareable()) {
|
||||||
@@ -104,7 +108,7 @@ static void injectToRuntime();
|
|||||||
}
|
}
|
||||||
|
|
||||||
-(instancetype)retain {
|
-(instancetype)retain {
|
||||||
if (refHolder.permanent()) { // TODO: consider storing `isPermanent` to self field.
|
if (permanent) {
|
||||||
[super retain];
|
[super retain];
|
||||||
} else {
|
} else {
|
||||||
refHolder.addRef<ErrorPolicy::kTerminate>();
|
refHolder.addRef<ErrorPolicy::kTerminate>();
|
||||||
@@ -113,7 +117,7 @@ static void injectToRuntime();
|
|||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)_tryRetain {
|
-(BOOL)_tryRetain {
|
||||||
if (refHolder.permanent()) {
|
if (permanent) {
|
||||||
return [super _tryRetain];
|
return [super _tryRetain];
|
||||||
} else {
|
} else {
|
||||||
return refHolder.tryAddRef<ErrorPolicy::kTerminate>();
|
return refHolder.tryAddRef<ErrorPolicy::kTerminate>();
|
||||||
@@ -121,7 +125,7 @@ static void injectToRuntime();
|
|||||||
}
|
}
|
||||||
|
|
||||||
-(oneway void)release {
|
-(oneway void)release {
|
||||||
if (refHolder.permanent()) {
|
if (permanent) {
|
||||||
[super release];
|
[super release];
|
||||||
} else {
|
} else {
|
||||||
refHolder.releaseRef();
|
refHolder.releaseRef();
|
||||||
|
|||||||
Reference in New Issue
Block a user