Skip to content

Commit f403357

Browse files
committed
Workarounds for issue johnezang#19 (the clang stuff) and issue johnezang#23. For issue johnezang#23, the code in the collection classes +load was removed and placed in a function with the __attribute__ ((constructor)) attribute. This is to work around an apparent bug when building JSONKit as a static library for iOS targets. @ohhorob also opened a bug with apple- # 9461567.
1 parent 7e4d3ec commit f403357

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

JSONKit.m

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,31 @@ - (void)releaseState;
609609
// classes receive the mutating methods, but this is handled by having those methods throw an exception when the ivar bit is set to immutable.
610610
// We adopt the same strategy here. It's both cleaner and gets rid of the method swizzling hackery used in JSONKit v1.4.
611611

612+
613+
// This is a workaround for issue #23 https://github.com/johnezang/JSONKit/pull/23
614+
// Basically, there seem to be a problem with using +load in static libraries on iOS. However, __attribute__ ((constructor)) does work correctly.
615+
// Since we do not require anything "special" that +load provides, and we can accomplish the same thing using __attribute__ ((constructor)), the +load logic was moved here.
616+
617+
static Class _JKArrayClass = NULL;
618+
static size_t _JKArrayInstanceSize = 0UL;
619+
static Class _JKDictionaryClass = NULL;
620+
static size_t _JKDictionaryInstanceSize = 0UL;
621+
622+
extern void jk_collectionClassLoadTimeInitialization(void) __attribute__ ((constructor));
623+
624+
void jk_collectionClassLoadTimeInitialization(void) {
625+
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Though technically not required, the run time environment at +load time may be less than ideal.
626+
627+
_JKArrayClass = objc_getClass("JKArray");
628+
_JKArrayInstanceSize = jk_max(16UL, class_getInstanceSize(_JKArrayClass));
629+
630+
_JKDictionaryClass = objc_getClass("JKDictionary");
631+
_JKDictionaryInstanceSize = jk_max(16UL, class_getInstanceSize(_JKDictionaryClass));
632+
633+
[pool release]; pool = NULL;
634+
}
635+
636+
612637
#pragma mark -
613638
@interface JKArray : NSMutableArray <NSCopying, NSMutableCopying, NSFastEnumeration> {
614639
id *objects;
@@ -618,19 +643,6 @@ @interface JKArray : NSMutableArray <NSCopying, NSMutableCopying, NSFastEnumerat
618643

619644
@implementation JKArray
620645

621-
static Class _JKArrayClass = NULL;
622-
static size_t _JKArrayInstanceSize = 0UL;
623-
624-
+ (void)load
625-
{
626-
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Though technically not required, the run time environment at +load time may be less than ideal.
627-
628-
_JKArrayClass = objc_getClass("JKArray");
629-
_JKArrayInstanceSize = jk_max(16UL, class_getInstanceSize(_JKArrayClass));
630-
631-
[pool release]; pool = NULL;
632-
}
633-
634646
+ (id)allocWithZone:(NSZone *)zone
635647
{
636648
#pragma unused(zone)
@@ -736,7 +748,11 @@ - (void)insertObject:(id)anObject atIndex:(NSUInteger)objectIndex
736748
if(mutations == 0UL) { [NSException raise:NSInternalInconsistencyException format:@"*** -[%@ %@]: mutating method sent to immutable object", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
737749
if(anObject == NULL) { [NSException raise:NSInvalidArgumentException format:@"*** -[%@ %@]: attempt to insert nil", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
738750
if(objectIndex > count) { [NSException raise:NSRangeException format:@"*** -[%@ %@]: index (%lu) beyond bounds (%lu)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), objectIndex, count + 1UL]; }
751+
#ifdef __clang_analyzer__
752+
[anObject retain]; // Stupid clang analyzer... Issue #19.
753+
#else
739754
anObject = [anObject retain];
755+
#endif
740756
_JKArrayInsertObjectAtIndex(self, anObject, objectIndex);
741757
mutations = (mutations == NSUIntegerMax) ? 1UL : mutations + 1UL;
742758
}
@@ -754,7 +770,11 @@ - (void)replaceObjectAtIndex:(NSUInteger)objectIndex withObject:(id)anObject
754770
if(mutations == 0UL) { [NSException raise:NSInternalInconsistencyException format:@"*** -[%@ %@]: mutating method sent to immutable object", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
755771
if(anObject == NULL) { [NSException raise:NSInvalidArgumentException format:@"*** -[%@ %@]: attempt to insert nil", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
756772
if(objectIndex >= count) { [NSException raise:NSRangeException format:@"*** -[%@ %@]: index (%lu) beyond bounds (%lu)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), objectIndex, count]; }
773+
#ifdef __clang_analyzer__
774+
[anObject retain]; // Stupid clang analyzer... Issue #19.
775+
#else
757776
anObject = [anObject retain];
777+
#endif
758778
_JKArrayReplaceObjectAtIndexWithObject(self, objectIndex, anObject);
759779
mutations = (mutations == NSUIntegerMax) ? 1UL : mutations + 1UL;
760780
}
@@ -836,19 +856,6 @@ @interface JKDictionary : NSMutableDictionary <NSCopying, NSMutableCopying, NSFa
836856

837857
@implementation JKDictionary
838858

839-
static Class _JKDictionaryClass = NULL;
840-
static size_t _JKDictionaryInstanceSize = 0UL;
841-
842-
+ (void)load
843-
{
844-
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Though technically not required, the run time environment at +load time may be less than ideal.
845-
846-
_JKDictionaryClass = objc_getClass("JKDictionary");
847-
_JKDictionaryInstanceSize = jk_max(16UL, class_getInstanceSize(_JKDictionaryClass));
848-
849-
[pool release]; pool = NULL;
850-
}
851-
852859
+ (id)allocWithZone:(NSZone *)zone
853860
{
854861
#pragma unused(zone)

0 commit comments

Comments
 (0)