diff --git a/MJExtension.podspec b/MJExtension.podspec index de57767a..432962cd 100644 --- a/MJExtension.podspec +++ b/MJExtension.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "MJExtension" - s.version = "3.0.13" + s.version = "3.0.14" s.ios.deployment_target = '6.0' s.osx.deployment_target = '10.8' s.summary = "A fast and convenient conversion between JSON and model" diff --git a/MJExtension/MJExtensionConst.h b/MJExtension/MJExtensionConst.h index ba8893a3..f5cf2aa4 100644 --- a/MJExtension/MJExtensionConst.h +++ b/MJExtension/MJExtensionConst.h @@ -4,6 +4,20 @@ #import +// 信号量 +#define MJExtensionSemaphoreCreate \ +static dispatch_semaphore_t signalSemaphore; \ +static dispatch_once_t onceTokenSemaphore; \ +dispatch_once(&onceTokenSemaphore, ^{ \ + signalSemaphore = dispatch_semaphore_create(1); \ +}); + +#define MJExtensionSemaphoreWait \ +dispatch_semaphore_wait(signalSemaphore, DISPATCH_TIME_FOREVER); + +#define MJExtensionSemaphoreSignal \ +dispatch_semaphore_signal(signalSemaphore); + // 过期 #define MJExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) @@ -85,4 +99,4 @@ extern NSString *const MJPropertyTypeClass; extern NSString *const MJPropertyTypeSEL; extern NSString *const MJPropertyTypeId; -#endif \ No newline at end of file +#endif diff --git a/MJExtension/MJFoundation.m b/MJExtension/MJFoundation.m index 23a7d8cd..3adc8420 100644 --- a/MJExtension/MJFoundation.m +++ b/MJExtension/MJFoundation.m @@ -10,15 +10,17 @@ #import "MJExtensionConst.h" #import -static NSSet *foundationClasses_; - @implementation MJFoundation -+ (NSSet *)foundationClasses ++ (BOOL)isClassFromFoundation:(Class)c { - if (foundationClasses_ == nil) { + if (c == [NSObject class] || c == [NSManagedObject class]) return YES; + + static NSSet *foundationClasses; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ // 集合中没有NSObject,因为几乎所有的类都是继承自NSObject,具体是不是NSObject需要特殊判断 - foundationClasses_ = [NSSet setWithObjects: + foundationClasses = [NSSet setWithObjects: [NSURL class], [NSDate class], [NSValue class], @@ -28,16 +30,10 @@ + (NSSet *)foundationClasses [NSDictionary class], [NSString class], [NSAttributedString class], nil]; - } - return foundationClasses_; -} - -+ (BOOL)isClassFromFoundation:(Class)c -{ - if (c == [NSObject class] || c == [NSManagedObject class]) return YES; + }); __block BOOL result = NO; - [[self foundationClasses] enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) { + [foundationClasses enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) { if ([c isSubclassOfClass:foundationClass]) { result = YES; *stop = YES; diff --git a/MJExtension/MJProperty.m b/MJExtension/MJProperty.m index 96710faf..ff57c6cb 100644 --- a/MJExtension/MJProperty.m +++ b/MJExtension/MJProperty.m @@ -31,12 +31,15 @@ - (instancetype)init #pragma mark - 缓存 + (instancetype)cachedPropertyWithProperty:(objc_property_t)property { + MJExtensionSemaphoreCreate + MJExtensionSemaphoreWait MJProperty *propertyObj = objc_getAssociatedObject(self, property); if (propertyObj == nil) { propertyObj = [[self alloc] init]; propertyObj.property = property; objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } + MJExtensionSemaphoreSignal return propertyObj; } @@ -150,21 +153,39 @@ - (void)setOriginKey:(id)originKey forClass:(Class)c - (void)setPorpertyKeys:(NSArray *)propertyKeys forClass:(Class)c { if (propertyKeys.count == 0) return; - self.propertyKeysDict[NSStringFromClass(c)] = propertyKeys; + NSString *key = NSStringFromClass(c); + if (!key) return; + + MJExtensionSemaphoreCreate + MJExtensionSemaphoreWait + self.propertyKeysDict[key] = propertyKeys; + MJExtensionSemaphoreSignal } + - (NSArray *)propertyKeysForClass:(Class)c { - return self.propertyKeysDict[NSStringFromClass(c)]; + NSString *key = NSStringFromClass(c); + if (!key) return nil; + return self.propertyKeysDict[key]; } /** 模型数组中的模型类型 */ - (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c { if (!objectClass) return; - self.objectClassInArrayDict[NSStringFromClass(c)] = objectClass; + NSString *key = NSStringFromClass(c); + if (!key) return; + + MJExtensionSemaphoreCreate + MJExtensionSemaphoreWait + self.objectClassInArrayDict[key] = objectClass; + MJExtensionSemaphoreSignal } + - (Class)objectClassInArrayForClass:(Class)c { - return self.objectClassInArrayDict[NSStringFromClass(c)]; + NSString *key = NSStringFromClass(c); + if (!key) return nil; + return self.objectClassInArrayDict[key]; } @end diff --git a/MJExtension/MJPropertyType.m b/MJExtension/MJPropertyType.m index 384beba5..012b4489 100755 --- a/MJExtension/MJPropertyType.m +++ b/MJExtension/MJPropertyType.m @@ -13,24 +13,26 @@ @implementation MJPropertyType -static NSMutableDictionary *types_; -+ (void)initialize -{ - types_ = [NSMutableDictionary dictionary]; -} - + (instancetype)cachedTypeWithCode:(NSString *)code { MJExtensionAssertParamNotNil2(code, nil); - @synchronized (self) { - MJPropertyType *type = types_[code]; - if (type == nil) { - type = [[self alloc] init]; - type.code = code; - types_[code] = type; - } - return type; + + static NSMutableDictionary *types; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + types = [NSMutableDictionary dictionary]; + }); + + MJExtensionSemaphoreCreate + MJExtensionSemaphoreWait + MJPropertyType *type = types[code]; + if (type == nil) { + type = [[self alloc] init]; + type.code = code; + types[code] = type; } + MJExtensionSemaphoreSignal + return type; } #pragma mark - 公共方法 diff --git a/MJExtension/NSObject+MJClass.m b/MJExtension/NSObject+MJClass.m index 46447a86..94911562 100644 --- a/MJExtension/NSObject+MJClass.m +++ b/MJExtension/NSObject+MJClass.m @@ -17,30 +17,28 @@ static const char MJAllowedCodingPropertyNamesKey = '\0'; static const char MJIgnoredCodingPropertyNamesKey = '\0'; -static NSMutableDictionary *allowedPropertyNamesDict_; -static NSMutableDictionary *ignoredPropertyNamesDict_; -static NSMutableDictionary *allowedCodingPropertyNamesDict_; -static NSMutableDictionary *ignoredCodingPropertyNamesDict_; - @implementation NSObject (MJClass) -+ (void)load -{ - allowedPropertyNamesDict_ = [NSMutableDictionary dictionary]; - ignoredPropertyNamesDict_ = [NSMutableDictionary dictionary]; - allowedCodingPropertyNamesDict_ = [NSMutableDictionary dictionary]; - ignoredCodingPropertyNamesDict_ = [NSMutableDictionary dictionary]; -} - + (NSMutableDictionary *)dictForKey:(const void *)key { - @synchronized (self) { - if (key == &MJAllowedPropertyNamesKey) return allowedPropertyNamesDict_; - if (key == &MJIgnoredPropertyNamesKey) return ignoredPropertyNamesDict_; - if (key == &MJAllowedCodingPropertyNamesKey) return allowedCodingPropertyNamesDict_; - if (key == &MJIgnoredCodingPropertyNamesKey) return ignoredCodingPropertyNamesDict_; - return nil; - } + static NSMutableDictionary *allowedPropertyNamesDict; + static NSMutableDictionary *ignoredPropertyNamesDict; + static NSMutableDictionary *allowedCodingPropertyNamesDict; + static NSMutableDictionary *ignoredCodingPropertyNamesDict; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + allowedPropertyNamesDict = [NSMutableDictionary dictionary]; + ignoredPropertyNamesDict = [NSMutableDictionary dictionary]; + allowedCodingPropertyNamesDict = [NSMutableDictionary dictionary]; + ignoredCodingPropertyNamesDict = [NSMutableDictionary dictionary]; + }); + + if (key == &MJAllowedPropertyNamesKey) return allowedPropertyNamesDict; + if (key == &MJIgnoredPropertyNamesKey) return ignoredPropertyNamesDict; + if (key == &MJAllowedCodingPropertyNamesKey) return allowedCodingPropertyNamesDict; + if (key == &MJIgnoredCodingPropertyNamesKey) return ignoredCodingPropertyNamesDict; + return nil; } + (void)mj_enumerateClasses:(MJClassesEnumeration)enumeration @@ -130,6 +128,7 @@ + (NSMutableArray *)mj_totalAllowedCodingPropertyNames { return [self mj_totalObjectsWithSelector:@selector(mj_allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey]; } + #pragma mark - block和方法处理:存储block的返回值 + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key { @@ -145,26 +144,32 @@ + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key + (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *)key { - NSMutableArray *array = [self dictForKey:key][NSStringFromClass(self)]; - if (array) return array; - - // 创建、存储 - [self dictForKey:key][NSStringFromClass(self)] = array = [NSMutableArray array]; + MJExtensionSemaphoreCreate + MJExtensionSemaphoreWait - if ([self respondsToSelector:selector]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - NSArray *subArray = [self performSelector:selector]; -#pragma clang diagnostic pop - if (subArray) { - [array addObjectsFromArray:subArray]; + NSMutableArray *array = [self dictForKey:key][NSStringFromClass(self)]; + if (array == nil) { + // 创建、存储 + [self dictForKey:key][NSStringFromClass(self)] = array = [NSMutableArray array]; + + if ([self respondsToSelector:selector]) { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Warc-performSelector-leaks" + NSArray *subArray = [self performSelector:selector]; + #pragma clang diagnostic pop + if (subArray) { + [array addObjectsFromArray:subArray]; + } } + + [self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) { + NSArray *subArray = objc_getAssociatedObject(c, key); + [array addObjectsFromArray:subArray]; + }]; } - [self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) { - NSArray *subArray = objc_getAssociatedObject(c, key); - [array addObjectsFromArray:subArray]; - }]; + MJExtensionSemaphoreSignal + return array; } @end diff --git a/MJExtension/NSObject+MJProperty.m b/MJExtension/NSObject+MJProperty.m index c9aff546..94bba552 100644 --- a/MJExtension/NSObject+MJProperty.m +++ b/MJExtension/NSObject+MJProperty.m @@ -27,31 +27,29 @@ @implementation NSObject (Property) -static NSMutableDictionary *replacedKeyFromPropertyNameDict_; -static NSMutableDictionary *replacedKeyFromPropertyName121Dict_; -static NSMutableDictionary *newValueFromOldValueDict_; -static NSMutableDictionary *objectClassInArrayDict_; -static NSMutableDictionary *cachedPropertiesDict_; - -+ (void)load -{ - replacedKeyFromPropertyNameDict_ = [NSMutableDictionary dictionary]; - replacedKeyFromPropertyName121Dict_ = [NSMutableDictionary dictionary]; - newValueFromOldValueDict_ = [NSMutableDictionary dictionary]; - objectClassInArrayDict_ = [NSMutableDictionary dictionary]; - cachedPropertiesDict_ = [NSMutableDictionary dictionary]; -} - + (NSMutableDictionary *)dictForKey:(const void *)key { - @synchronized (self) { - if (key == &MJReplacedKeyFromPropertyNameKey) return replacedKeyFromPropertyNameDict_; - if (key == &MJReplacedKeyFromPropertyName121Key) return replacedKeyFromPropertyName121Dict_; - if (key == &MJNewValueFromOldValueKey) return newValueFromOldValueDict_; - if (key == &MJObjectClassInArrayKey) return objectClassInArrayDict_; - if (key == &MJCachedPropertiesKey) return cachedPropertiesDict_; - return nil; - } + static NSMutableDictionary *replacedKeyFromPropertyNameDict; + static NSMutableDictionary *replacedKeyFromPropertyName121Dict; + static NSMutableDictionary *newValueFromOldValueDict; + static NSMutableDictionary *objectClassInArrayDict; + static NSMutableDictionary *cachedPropertiesDict; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + replacedKeyFromPropertyNameDict = [NSMutableDictionary dictionary]; + replacedKeyFromPropertyName121Dict = [NSMutableDictionary dictionary]; + newValueFromOldValueDict = [NSMutableDictionary dictionary]; + objectClassInArrayDict = [NSMutableDictionary dictionary]; + cachedPropertiesDict = [NSMutableDictionary dictionary]; + }); + + if (key == &MJReplacedKeyFromPropertyNameKey) return replacedKeyFromPropertyNameDict; + if (key == &MJReplacedKeyFromPropertyName121Key) return replacedKeyFromPropertyName121Dict; + if (key == &MJNewValueFromOldValueKey) return newValueFromOldValueDict; + if (key == &MJObjectClassInArrayKey) return objectClassInArrayDict; + if (key == &MJCachedPropertiesKey) return cachedPropertiesDict; + return nil; } #pragma mark - --私有方法-- diff --git a/MJExtensionExample.xcodeproj/project.pbxproj b/MJExtensionExample.xcodeproj/project.pbxproj index a2acda2f..18c2f80a 100644 --- a/MJExtensionExample.xcodeproj/project.pbxproj +++ b/MJExtensionExample.xcodeproj/project.pbxproj @@ -881,6 +881,7 @@ C37522BF1CF0AC330037E747 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ };