Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 81dd9c2

Browse files
committed
Optimized property setting and conversion
1 parent 4499f28 commit 81dd9c2

File tree

2 files changed

+110
-32
lines changed

2 files changed

+110
-32
lines changed

React/Base/RCTConvert.m

Lines changed: 109 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,24 +1075,64 @@ BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json)
10751075
}
10761076

10771077
@try {
1078-
// Get converted value
1078+
10791079
NSMethodSignature *signature = [RCTConvert methodSignatureForSelector:type];
1080-
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
1081-
[invocation setArgument:&type atIndex:1];
1082-
[invocation setArgument:&json atIndex:2];
1083-
[invocation invokeWithTarget:[RCTConvert class]];
1084-
NSUInteger length = [signature methodReturnLength];
1085-
void *value = malloc(length);
1086-
[invocation getReturnValue:value];
1087-
1088-
// Set converted value
1089-
signature = [target methodSignatureForSelector:setter];
1090-
invocation = [NSInvocation invocationWithMethodSignature:signature];
1091-
[invocation setArgument:&setter atIndex:1];
1092-
[invocation setArgument:value atIndex:2];
1093-
[invocation invokeWithTarget:target];
1094-
free(value);
1080+
switch (signature.methodReturnType[0]) {
1081+
1082+
#define RCT_SET_CASE(_value, _type) \
1083+
case _value: { \
1084+
_type (*convert)(id, SEL, id) = (typeof(convert))objc_msgSend; \
1085+
void (*set)(id, SEL, _type) = (typeof(set))objc_msgSend; \
1086+
set(target, setter, convert([RCTConvert class], type, json)); \
1087+
break; \
1088+
}
10951089

1090+
RCT_SET_CASE(':', SEL)
1091+
RCT_SET_CASE('*', const char *)
1092+
RCT_SET_CASE('c', char)
1093+
RCT_SET_CASE('C', unsigned char)
1094+
RCT_SET_CASE('s', short)
1095+
RCT_SET_CASE('S', unsigned short)
1096+
RCT_SET_CASE('i', int)
1097+
RCT_SET_CASE('I', unsigned int)
1098+
RCT_SET_CASE('l', long)
1099+
RCT_SET_CASE('L', unsigned long)
1100+
RCT_SET_CASE('q', long long)
1101+
RCT_SET_CASE('Q', unsigned long long)
1102+
RCT_SET_CASE('f', float)
1103+
RCT_SET_CASE('d', double)
1104+
RCT_SET_CASE('B', BOOL)
1105+
RCT_SET_CASE('^', void *)
1106+
1107+
case '@': {
1108+
id (*convert)(id, SEL, id) = (typeof(convert))objc_msgSend;
1109+
void (*set)(id, SEL, id) = (typeof(set))objc_msgSend;
1110+
set(target, setter, convert([RCTConvert class], type, json));
1111+
break;
1112+
}
1113+
case '{':
1114+
default: {
1115+
1116+
// Get converted value
1117+
void *value = malloc(signature.methodReturnLength);
1118+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
1119+
[invocation setTarget:[RCTConvert class]];
1120+
[invocation setSelector:type];
1121+
[invocation setArgument:&json atIndex:2];
1122+
[invocation invoke];
1123+
[invocation getReturnValue:value];
1124+
1125+
// Set converted value
1126+
signature = [target methodSignatureForSelector:setter];
1127+
invocation = [NSInvocation invocationWithMethodSignature:signature];
1128+
[invocation setArgument:&setter atIndex:1];
1129+
[invocation setArgument:value atIndex:2];
1130+
[invocation invokeWithTarget:target];
1131+
free(value);
1132+
1133+
break;
1134+
}
1135+
}
10961136
return YES;
10971137
}
10981138
@catch (NSException *exception) {
@@ -1128,22 +1168,60 @@ BOOL RCTCopyProperty(id target, id source, NSString *keyPath)
11281168
return NO;
11291169
}
11301170

1131-
// Get value
11321171
NSMethodSignature *signature = [source methodSignatureForSelector:getter];
1133-
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
1134-
[invocation setArgument:&getter atIndex:1];
1135-
[invocation invokeWithTarget:source];
1136-
NSUInteger length = [signature methodReturnLength];
1137-
void *value = malloc(length);
1138-
[invocation getReturnValue:value];
1139-
1140-
// Set value
1141-
signature = [target methodSignatureForSelector:setter];
1142-
invocation = [NSInvocation invocationWithMethodSignature:signature];
1143-
[invocation setArgument:&setter atIndex:1];
1144-
[invocation setArgument:value atIndex:2];
1145-
[invocation invokeWithTarget:target];
1146-
free(value);
1172+
switch (signature.methodReturnType[0]) {
1173+
1174+
#define RCT_COPY_CASE(_value, _type) \
1175+
case _value: { \
1176+
_type (*get)(id, SEL) = (typeof(get))objc_msgSend; \
1177+
void (*set)(id, SEL, _type) = (typeof(set))objc_msgSend; \
1178+
set(target, setter, get(source, getter)); \
1179+
break; \
1180+
}
11471181

1182+
RCT_COPY_CASE(':', SEL)
1183+
RCT_COPY_CASE('*', const char *)
1184+
RCT_COPY_CASE('c', char)
1185+
RCT_COPY_CASE('C', unsigned char)
1186+
RCT_COPY_CASE('s', short)
1187+
RCT_COPY_CASE('S', unsigned short)
1188+
RCT_COPY_CASE('i', int)
1189+
RCT_COPY_CASE('I', unsigned int)
1190+
RCT_COPY_CASE('l', long)
1191+
RCT_COPY_CASE('L', unsigned long)
1192+
RCT_COPY_CASE('q', long long)
1193+
RCT_COPY_CASE('Q', unsigned long long)
1194+
RCT_COPY_CASE('f', float)
1195+
RCT_COPY_CASE('d', double)
1196+
RCT_COPY_CASE('B', BOOL)
1197+
RCT_COPY_CASE('^', void *)
1198+
1199+
case '@': {
1200+
id (*get)(id, SEL) = (typeof(get))objc_msgSend;
1201+
void (*set)(id, SEL, id) = (typeof(set))objc_msgSend;
1202+
set(target, setter, get(source, getter));
1203+
break;
1204+
}
1205+
case '{':
1206+
default: {
1207+
1208+
// Get value
1209+
void *value = malloc(signature.methodReturnLength);
1210+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
1211+
[invocation setArgument:&getter atIndex:1];
1212+
[invocation invokeWithTarget:source];
1213+
[invocation getReturnValue:value];
1214+
1215+
// Set value
1216+
signature = [target methodSignatureForSelector:setter];
1217+
invocation = [NSInvocation invocationWithMethodSignature:signature];
1218+
[invocation setArgument:&setter atIndex:1];
1219+
[invocation setArgument:value atIndex:2];
1220+
[invocation invokeWithTarget:target];
1221+
free(value);
1222+
1223+
break;
1224+
}
1225+
}
11481226
return YES;
11491227
}

React/Base/RCTModuleMethod.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ - (instancetype)initWithObjCMethodName:(NSString *)objCMethodName
9191
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
9292
_logic \
9393
[invocation setArgument:&value atIndex:index]; \
94-
}]; \
94+
}];
9595

9696
void (^addBlockArgument)(void) = ^{
9797
RCT_ARG_BLOCK(

0 commit comments

Comments
 (0)