Last active
June 25, 2020 14:15
-
-
Save knebekaizer/8e924ba8732f914d10c3ccb533831ebb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <bool retainAutorelease> | |
static ALWAYS_INLINE id Kotlin_ObjCExport_refToObjCImpl(ObjHeader* obj) { | |
if (obj == nullptr) return nullptr; | |
if (obj->has_meta_object()) { | |
id associatedObject = GetAssociatedObject(obj); | |
if (associatedObject != nullptr) { | |
return retainAutorelease ? objc_retainAutoreleaseReturnValue(associatedObject) : associatedObject; | |
} | |
} | |
// TODO: propagate [retainAutorelease] to the code below. | |
convertReferenceToObjC converter = (convertReferenceToObjC)obj->type_info()->writableInfo_->objCExport.convert; | |
if (converter != nullptr) { | |
return converter(obj); | |
} | |
return Kotlin_ObjCExport_refToObjC_slowpath(obj); | |
} | |
/** | |
Здесь нехорошо то, что функция `Kotlin_ObjCExport_refToObjCImpl` смешивает две проблемных области (domains): | |
1. Business domain: create and store (slow path) or fetch (fast path) the associated object | |
2. ARC domain: retain policy | |
Try orthogonal design by Separation of Concerns: separate policy from business code: | |
*/ | |
template <typename RetainAutoreleasePolicy> | |
static ALWAYS_INLINE id Kotlin_ObjCExport_refToObjCImpl(ObjHeader* obj) { | |
if (obj == nullptr) return nullptr; | |
if (obj->has_meta_object()) { | |
if (id associatedObject = GetAssociatedObject(obj)) { | |
return RetainAutoreleasePolicy(associatedObject); | |
} | |
} | |
// ... no changes below... | |
} | |
/// Usage example: | |
std::function<id (id)> doRetain = [](id obj) { return objc_retainAutoreleaseReturnValue(obj); }; | |
std::function<id (id)> doNotRetain = [](id obj) { return obj; }; | |
id foo = Kotlin_ObjCExport_refToObjCImpl<doRetain>(obj); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment