NSKeyValueCoding: Safe-Caching for -[NSObject valueForKey:] (#445)

* KVC Caching Implementation

* Do not ignore struct name when comparing type encoding as NSPoint and NSSize have the same layout

* Use fast-path when using Objective-C 2

* Guard old ValueForKey function when using the fast-path

* Add basic NSKeyValueCoding tests

* Update Copyright Years

* NSKeyValueCoding+Caching: Add Versioning to IVar Slot

* safe_caching: Remove Guards

* Add type encoding helper header

* Rename geometry structs (NSRect, NSPoint, NSSize) for toll-free bridging with CoreGraphics

* Move CG struct definitions to CFCGTypes.h

* Update known struct encoding prefixes

* Windows 64-bit is LLP64 and not LP64

* Re-order to avoid complier warning

---------

Co-authored-by: rfm <richardfrithmacdonald@gmail.com>
This commit is contained in:
Hugo Melder 2024-10-29 06:12:34 -07:00 committed by GitHub
parent 4f0a8d60c2
commit 6eef1c3289
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 1549 additions and 49 deletions

View file

@ -28,6 +28,7 @@
*/
#import "common.h"
#import "typeEncodingHelper.h"
#import "Foundation/NSValue.h"
#import "Foundation/NSCoder.h"
#import "Foundation/NSDictionary.h"
@ -411,28 +412,28 @@ static NSLock *placeholderLock;
size = strlen(objctype)+1;
[coder encodeValueOfObjCType: @encode(unsigned) at: &size];
[coder encodeArrayOfObjCType: @encode(signed char) count: size at: objctype];
if (strncmp("{_NSSize=", objctype, 9) == 0)
if (strncmp(CGSIZE_ENCODING_PREFIX, objctype, strlen(CGSIZE_ENCODING_PREFIX)) == 0)
{
NSSize v = [self sizeValue];
[coder encodeValueOfObjCType: objctype at: &v];
return;
}
else if (strncmp("{_NSPoint=", objctype, 10) == 0)
else if (strncmp(CGPOINT_ENCODING_PREFIX, objctype, strlen(CGPOINT_ENCODING_PREFIX)) == 0)
{
NSPoint v = [self pointValue];
[coder encodeValueOfObjCType: objctype at: &v];
return;
}
else if (strncmp("{_NSRect=", objctype, 9) == 0)
else if (strncmp(CGRECT_ENCODING_PREFIX, objctype, strlen(CGRECT_ENCODING_PREFIX)) == 0)
{
NSRect v = [self rectValue];
[coder encodeValueOfObjCType: objctype at: &v];
return;
}
else if (strncmp("{_NSRange=", objctype, 10) == 0)
else if (strncmp(NSRANGE_ENCODING_PREFIX, objctype, strlen(NSRANGE_ENCODING_PREFIX)) == 0)
{
NSRange v = [self rangeValue];
@ -480,13 +481,13 @@ static NSLock *placeholderLock;
[coder decodeArrayOfObjCType: @encode(signed char)
count: size
at: (void*)objctype];
if (strncmp("{_NSSize=", objctype, 9) == 0)
if (strncmp(CGSIZE_ENCODING_PREFIX, objctype, strlen(CGSIZE_ENCODING_PREFIX)) == 0)
c = [abstractClass valueClassWithObjCType: @encode(NSSize)];
else if (strncmp("{_NSPoint=", objctype, 10) == 0)
else if (strncmp(CGPOINT_ENCODING_PREFIX, objctype, strlen(CGPOINT_ENCODING_PREFIX)) == 0)
c = [abstractClass valueClassWithObjCType: @encode(NSPoint)];
else if (strncmp("{_NSRect=", objctype, 9) == 0)
else if (strncmp(CGRECT_ENCODING_PREFIX, objctype, strlen(CGRECT_ENCODING_PREFIX)) == 0)
c = [abstractClass valueClassWithObjCType: @encode(NSRect)];
else if (strncmp("{_NSRange=", objctype, 10) == 0)
else if (strncmp(NSRANGE_ENCODING_PREFIX, objctype, strlen(NSRANGE_ENCODING_PREFIX)) == 0)
c = [abstractClass valueClassWithObjCType: @encode(NSRange)];
else
c = [abstractClass valueClassWithObjCType: objctype];