From 8a6f9015f1c72bdfa4e2d4aebe5821e719e3872c Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Tue, 5 Jun 2018 11:50:58 +0300 Subject: [PATCH] Fix non-public API usage when uploading to AppStore Don't implement category for NSBlock class --- runtime/src/main/cpp/ObjCExport.mm | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/runtime/src/main/cpp/ObjCExport.mm b/runtime/src/main/cpp/ObjCExport.mm index a89b3157d15..e42b4131547 100644 --- a/runtime/src/main/cpp/ObjCExport.mm +++ b/runtime/src/main/cpp/ObjCExport.mm @@ -373,6 +373,8 @@ static ALWAYS_INLINE OBJ_GETTER(convertUnmappedObjCObject, id obj) { RETURN_RESULT_OF(AllocInstanceWithAssociatedObject, typeInfo, objc_retain(obj)); } +static OBJ_GETTER(blockToKotlinImp, id self, SEL cmd); + @interface NSObject (NSObjectToKotlin) @end; @@ -384,6 +386,20 @@ static ALWAYS_INLINE OBJ_GETTER(convertUnmappedObjCObject, id obj) { -(void)releaseAsAssociatedObject { objc_release(self); } + ++(void)load { + SEL toKotlinSelector = @selector(toKotlin:); + Method toKotlinMethod = class_getClassMethod([NSObject class], toKotlinSelector); + RuntimeAssert(toKotlinMethod != nullptr, ""); + const char* toKotlinTypeEncoding = method_getTypeEncoding(toKotlinMethod); + + Class nsBlockClass = objc_getClass("NSBlock"); + RuntimeAssert(nsBlockClass != nullptr, "NSBlock class not found"); + + // Note: can't add it with category, because it would be considered as private API usage. + BOOL added = class_addMethod(nsBlockClass, toKotlinSelector, (IMP)blockToKotlinImp, toKotlinTypeEncoding); + RuntimeAssert(added, "Unable to add 'toKotlin:' method to NSBlock class"); +} @end; @interface NSString (NSStringToKotlin) @@ -458,12 +474,6 @@ static Class __NSCFBooleanClass = nullptr; } @end; -@interface NSBlock -@end; - -@interface NSBlock (NSBlockToKotlin) -@end; - struct Block_descriptor_1; // Based on https://clang.llvm.org/docs/Block-ABI-Apple.html and libclosure source. @@ -545,20 +555,12 @@ static const TypeInfo* getFunctionTypeInfoForBlock(id block) { return Kotlin_ObjCExport_functionAdaptersToBlock[parameterCount]; } -@implementation NSBlock (NSBlockToKotlin) --(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { - +static OBJ_GETTER(blockToKotlinImp, id self, SEL cmd) { const TypeInfo* typeInfo = getFunctionTypeInfoForBlock(self); RETURN_RESULT_OF(AllocInstanceWithAssociatedObject, typeInfo, objc_retainBlock(self)); // TODO: call (Any) constructor? } --(void)releaseAsAssociatedObject { - objc_release(self); -} - -@end; - static id Kotlin_ObjCExport_refToObjC_slowpath(ObjHeader* obj); template