Optimized property setting and conversion
This commit is contained in:
parent
4499f28c1d
commit
81dd9c27ea
|
@ -1075,24 +1075,64 @@ BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json)
|
||||||
}
|
}
|
||||||
|
|
||||||
@try {
|
@try {
|
||||||
// Get converted value
|
|
||||||
NSMethodSignature *signature = [RCTConvert methodSignatureForSelector:type];
|
NSMethodSignature *signature = [RCTConvert methodSignatureForSelector:type];
|
||||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
switch (signature.methodReturnType[0]) {
|
||||||
[invocation setArgument:&type atIndex:1];
|
|
||||||
[invocation setArgument:&json atIndex:2];
|
|
||||||
[invocation invokeWithTarget:[RCTConvert class]];
|
|
||||||
NSUInteger length = [signature methodReturnLength];
|
|
||||||
void *value = malloc(length);
|
|
||||||
[invocation getReturnValue:value];
|
|
||||||
|
|
||||||
// Set converted value
|
#define RCT_SET_CASE(_value, _type) \
|
||||||
signature = [target methodSignatureForSelector:setter];
|
case _value: { \
|
||||||
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
_type (*convert)(id, SEL, id) = (typeof(convert))objc_msgSend; \
|
||||||
[invocation setArgument:&setter atIndex:1];
|
void (*set)(id, SEL, _type) = (typeof(set))objc_msgSend; \
|
||||||
[invocation setArgument:value atIndex:2];
|
set(target, setter, convert([RCTConvert class], type, json)); \
|
||||||
[invocation invokeWithTarget:target];
|
break; \
|
||||||
free(value);
|
}
|
||||||
|
|
||||||
|
RCT_SET_CASE(':', SEL)
|
||||||
|
RCT_SET_CASE('*', const char *)
|
||||||
|
RCT_SET_CASE('c', char)
|
||||||
|
RCT_SET_CASE('C', unsigned char)
|
||||||
|
RCT_SET_CASE('s', short)
|
||||||
|
RCT_SET_CASE('S', unsigned short)
|
||||||
|
RCT_SET_CASE('i', int)
|
||||||
|
RCT_SET_CASE('I', unsigned int)
|
||||||
|
RCT_SET_CASE('l', long)
|
||||||
|
RCT_SET_CASE('L', unsigned long)
|
||||||
|
RCT_SET_CASE('q', long long)
|
||||||
|
RCT_SET_CASE('Q', unsigned long long)
|
||||||
|
RCT_SET_CASE('f', float)
|
||||||
|
RCT_SET_CASE('d', double)
|
||||||
|
RCT_SET_CASE('B', BOOL)
|
||||||
|
RCT_SET_CASE('^', void *)
|
||||||
|
|
||||||
|
case '@': {
|
||||||
|
id (*convert)(id, SEL, id) = (typeof(convert))objc_msgSend;
|
||||||
|
void (*set)(id, SEL, id) = (typeof(set))objc_msgSend;
|
||||||
|
set(target, setter, convert([RCTConvert class], type, json));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '{':
|
||||||
|
default: {
|
||||||
|
|
||||||
|
// Get converted value
|
||||||
|
void *value = malloc(signature.methodReturnLength);
|
||||||
|
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||||
|
[invocation setTarget:[RCTConvert class]];
|
||||||
|
[invocation setSelector:type];
|
||||||
|
[invocation setArgument:&json atIndex:2];
|
||||||
|
[invocation invoke];
|
||||||
|
[invocation getReturnValue:value];
|
||||||
|
|
||||||
|
// Set converted value
|
||||||
|
signature = [target methodSignatureForSelector:setter];
|
||||||
|
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||||
|
[invocation setArgument:&setter atIndex:1];
|
||||||
|
[invocation setArgument:value atIndex:2];
|
||||||
|
[invocation invokeWithTarget:target];
|
||||||
|
free(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@catch (NSException *exception) {
|
@catch (NSException *exception) {
|
||||||
|
@ -1128,22 +1168,60 @@ BOOL RCTCopyProperty(id target, id source, NSString *keyPath)
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value
|
|
||||||
NSMethodSignature *signature = [source methodSignatureForSelector:getter];
|
NSMethodSignature *signature = [source methodSignatureForSelector:getter];
|
||||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
switch (signature.methodReturnType[0]) {
|
||||||
[invocation setArgument:&getter atIndex:1];
|
|
||||||
[invocation invokeWithTarget:source];
|
|
||||||
NSUInteger length = [signature methodReturnLength];
|
|
||||||
void *value = malloc(length);
|
|
||||||
[invocation getReturnValue:value];
|
|
||||||
|
|
||||||
// Set value
|
#define RCT_COPY_CASE(_value, _type) \
|
||||||
signature = [target methodSignatureForSelector:setter];
|
case _value: { \
|
||||||
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
_type (*get)(id, SEL) = (typeof(get))objc_msgSend; \
|
||||||
[invocation setArgument:&setter atIndex:1];
|
void (*set)(id, SEL, _type) = (typeof(set))objc_msgSend; \
|
||||||
[invocation setArgument:value atIndex:2];
|
set(target, setter, get(source, getter)); \
|
||||||
[invocation invokeWithTarget:target];
|
break; \
|
||||||
free(value);
|
}
|
||||||
|
|
||||||
|
RCT_COPY_CASE(':', SEL)
|
||||||
|
RCT_COPY_CASE('*', const char *)
|
||||||
|
RCT_COPY_CASE('c', char)
|
||||||
|
RCT_COPY_CASE('C', unsigned char)
|
||||||
|
RCT_COPY_CASE('s', short)
|
||||||
|
RCT_COPY_CASE('S', unsigned short)
|
||||||
|
RCT_COPY_CASE('i', int)
|
||||||
|
RCT_COPY_CASE('I', unsigned int)
|
||||||
|
RCT_COPY_CASE('l', long)
|
||||||
|
RCT_COPY_CASE('L', unsigned long)
|
||||||
|
RCT_COPY_CASE('q', long long)
|
||||||
|
RCT_COPY_CASE('Q', unsigned long long)
|
||||||
|
RCT_COPY_CASE('f', float)
|
||||||
|
RCT_COPY_CASE('d', double)
|
||||||
|
RCT_COPY_CASE('B', BOOL)
|
||||||
|
RCT_COPY_CASE('^', void *)
|
||||||
|
|
||||||
|
case '@': {
|
||||||
|
id (*get)(id, SEL) = (typeof(get))objc_msgSend;
|
||||||
|
void (*set)(id, SEL, id) = (typeof(set))objc_msgSend;
|
||||||
|
set(target, setter, get(source, getter));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '{':
|
||||||
|
default: {
|
||||||
|
|
||||||
|
// Get value
|
||||||
|
void *value = malloc(signature.methodReturnLength);
|
||||||
|
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||||
|
[invocation setArgument:&getter atIndex:1];
|
||||||
|
[invocation invokeWithTarget:source];
|
||||||
|
[invocation getReturnValue:value];
|
||||||
|
|
||||||
|
// Set value
|
||||||
|
signature = [target methodSignatureForSelector:setter];
|
||||||
|
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||||
|
[invocation setArgument:&setter atIndex:1];
|
||||||
|
[invocation setArgument:value atIndex:2];
|
||||||
|
[invocation invokeWithTarget:target];
|
||||||
|
free(value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ RCT_NOT_IMPLEMENTED(-init)
|
||||||
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
|
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
|
||||||
_logic \
|
_logic \
|
||||||
[invocation setArgument:&value atIndex:index]; \
|
[invocation setArgument:&value atIndex:index]; \
|
||||||
}]; \
|
}];
|
||||||
|
|
||||||
void (^addBlockArgument)(void) = ^{
|
void (^addBlockArgument)(void) = ^{
|
||||||
RCT_ARG_BLOCK(
|
RCT_ARG_BLOCK(
|
||||||
|
|
Loading…
Reference in New Issue