修复了部分UI,阿里推送token,wifi重名的问题
This commit is contained in:
@@ -4,12 +4,24 @@
|
||||
//
|
||||
// Created by mj on 14-1-15.
|
||||
// Copyright (c) 2014年 小码哥. All rights reserved.
|
||||
// 代码地址:https://github.com/CoderMJLee/MJExtension
|
||||
// 代码地址:http://code4app.com/ios/%E5%AD%97%E5%85%B8-JSON-%E4%B8%8E%E6%A8%A1%E5%9E%8B%E7%9A%84%E8%BD%AC%E6%8D%A2/5339992a933bf062608b4c57
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "NSObject+MJCoding.h"
|
||||
#import "NSObject+MJProperty.h"
|
||||
#import "NSObject+MJClass.h"
|
||||
#import "NSObject+MJKeyValue.h"
|
||||
#import "NSString+MJExtension.h"
|
||||
#import "MJExtensionConst.h"
|
||||
#import "MJExtensionConst.h"
|
||||
|
||||
#import "MJFoundation.h"
|
||||
|
||||
//! Project version number for MJExtension.
|
||||
FOUNDATION_EXPORT double MJExtensionVersionNumber;
|
||||
|
||||
//! Project version string for MJExtension.
|
||||
FOUNDATION_EXPORT const unsigned char MJExtensionVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <MJExtension/PublicHeader.h>
|
||||
|
||||
|
||||
|
||||
Regular → Executable
+44
-18
@@ -4,6 +4,25 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef MJ_LOCK
|
||||
#define MJ_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
|
||||
#endif
|
||||
|
||||
#ifndef MJ_UNLOCK
|
||||
#define MJ_UNLOCK(lock) dispatch_semaphore_signal(lock);
|
||||
#endif
|
||||
|
||||
// 信号量
|
||||
#define MJExtensionSemaphoreCreate \
|
||||
static dispatch_semaphore_t signalSemaphore; \
|
||||
static dispatch_once_t onceTokenSemaphore; \
|
||||
dispatch_once(&onceTokenSemaphore, ^{ \
|
||||
signalSemaphore = dispatch_semaphore_create(1); \
|
||||
});
|
||||
|
||||
#define MJExtensionSemaphoreWait MJ_LOCK(signalSemaphore)
|
||||
#define MJExtensionSemaphoreSignal MJ_UNLOCK(signalSemaphore)
|
||||
|
||||
// 过期
|
||||
#define MJExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
|
||||
|
||||
@@ -58,31 +77,38 @@ MJExtensionAssert2((param) != nil, returnValue)
|
||||
* 打印所有的属性
|
||||
*/
|
||||
#define MJLogAllIvars \
|
||||
-(NSString *)description \
|
||||
- (NSString *)description \
|
||||
{ \
|
||||
return [self mj_keyValues].description; \
|
||||
}
|
||||
#define MJExtensionLogAllProperties MJLogAllIvars
|
||||
|
||||
/** 仅在 Debugger 展示所有的属性 */
|
||||
#define MJImplementDebugDescription \
|
||||
- (NSString *)debugDescription \
|
||||
{ \
|
||||
return [self mj_keyValues].debugDescription; \
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型(属性类型)
|
||||
*/
|
||||
extern NSString *const MJPropertyTypeInt;
|
||||
extern NSString *const MJPropertyTypeShort;
|
||||
extern NSString *const MJPropertyTypeFloat;
|
||||
extern NSString *const MJPropertyTypeDouble;
|
||||
extern NSString *const MJPropertyTypeLong;
|
||||
extern NSString *const MJPropertyTypeLongLong;
|
||||
extern NSString *const MJPropertyTypeChar;
|
||||
extern NSString *const MJPropertyTypeBOOL1;
|
||||
extern NSString *const MJPropertyTypeBOOL2;
|
||||
extern NSString *const MJPropertyTypePointer;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeInt;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeShort;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeFloat;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeDouble;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeLong;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeLongLong;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeChar;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeBOOL1;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeBOOL2;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypePointer;
|
||||
|
||||
extern NSString *const MJPropertyTypeIvar;
|
||||
extern NSString *const MJPropertyTypeMethod;
|
||||
extern NSString *const MJPropertyTypeBlock;
|
||||
extern NSString *const MJPropertyTypeClass;
|
||||
extern NSString *const MJPropertyTypeSEL;
|
||||
extern NSString *const MJPropertyTypeId;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeIvar;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeMethod;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeBlock;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeClass;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeSEL;
|
||||
FOUNDATION_EXPORT NSString *const MJPropertyTypeId;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Regular → Executable
Regular → Executable
+3
@@ -9,5 +9,8 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MJFoundation : NSObject
|
||||
|
||||
+ (BOOL)isClassFromFoundation:(Class)c;
|
||||
+ (BOOL)isFromNSObjectProtocolProperty:(NSString *)propertyName;
|
||||
|
||||
@end
|
||||
|
||||
Regular → Executable
+43
-21
@@ -9,35 +9,32 @@
|
||||
#import "MJFoundation.h"
|
||||
#import "MJExtensionConst.h"
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
static NSSet *foundationClasses_;
|
||||
#import "objc/runtime.h"
|
||||
|
||||
@implementation MJFoundation
|
||||
|
||||
+ (NSSet *)foundationClasses
|
||||
{
|
||||
if (foundationClasses_ == nil) {
|
||||
// 集合中没有NSObject,因为几乎所有的类都是继承自NSObject,具体是不是NSObject需要特殊判断
|
||||
foundationClasses_ = [NSSet setWithObjects:
|
||||
[NSURL class],
|
||||
[NSDate class],
|
||||
[NSValue class],
|
||||
[NSData class],
|
||||
[NSError class],
|
||||
[NSArray class],
|
||||
[NSDictionary class],
|
||||
[NSString class],
|
||||
[NSAttributedString class], nil];
|
||||
}
|
||||
return foundationClasses_;
|
||||
}
|
||||
|
||||
+ (BOOL)isClassFromFoundation:(Class)c
|
||||
{
|
||||
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:
|
||||
[NSURL class],
|
||||
[NSDate class],
|
||||
[NSValue class],
|
||||
[NSData class],
|
||||
[NSError class],
|
||||
[NSArray class],
|
||||
[NSDictionary class],
|
||||
[NSString class],
|
||||
[NSAttributedString class], nil];
|
||||
});
|
||||
|
||||
__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;
|
||||
@@ -45,4 +42,29 @@ static NSSet *foundationClasses_;
|
||||
}];
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL)isFromNSObjectProtocolProperty:(NSString *)propertyName
|
||||
{
|
||||
if (!propertyName) return NO;
|
||||
|
||||
static NSSet<NSString *> *objectProtocolPropertyNames;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
unsigned int count = 0;
|
||||
objc_property_t *propertyList = protocol_copyPropertyList(@protocol(NSObject), &count);
|
||||
NSMutableSet *propertyNames = [NSMutableSet setWithCapacity:count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
objc_property_t property = propertyList[i];
|
||||
NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
|
||||
if (propertyName) {
|
||||
[propertyNames addObject:propertyName];
|
||||
}
|
||||
}
|
||||
objectProtocolPropertyNames = [propertyNames copy];
|
||||
free(propertyList);
|
||||
});
|
||||
|
||||
return [objectProtocolPropertyNames containsObject:propertyName];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Regular → Executable
Regular → Executable
+46
-5
@@ -10,10 +10,13 @@
|
||||
#import "MJFoundation.h"
|
||||
#import "MJExtensionConst.h"
|
||||
#import <objc/message.h>
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
@interface MJProperty()
|
||||
@property (strong, nonatomic) NSMutableDictionary *propertyKeysDict;
|
||||
@property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict;
|
||||
@property (strong, nonatomic) dispatch_semaphore_t propertyKeysLock;
|
||||
@property (strong, nonatomic) dispatch_semaphore_t objectClassInArrayLock;
|
||||
@end
|
||||
|
||||
@implementation MJProperty
|
||||
@@ -24,6 +27,8 @@
|
||||
if (self = [super init]) {
|
||||
_propertyKeysDict = [NSMutableDictionary dictionary];
|
||||
_objectClassInArrayDict = [NSMutableDictionary dictionary];
|
||||
_propertyKeysLock = dispatch_semaphore_create(1);
|
||||
_objectClassInArrayLock = dispatch_semaphore_create(1);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -69,7 +74,19 @@
|
||||
- (id)valueForObject:(id)object
|
||||
{
|
||||
if (self.type.KVCDisabled) return [NSNull null];
|
||||
return [object valueForKey:self.name];
|
||||
|
||||
id value = [object valueForKey:self.name];
|
||||
|
||||
// 32位BOOL类型转换json后成Int类型
|
||||
/** https://github.com/CoderMJLee/MJExtension/issues/545 */
|
||||
// 32 bit device OR 32 bit Simulator
|
||||
#if defined(__arm__) || (TARGET_OS_SIMULATOR && !__LP64__)
|
||||
if (self.type.isBoolType) {
|
||||
value = @([(NSNumber *)value boolValue]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,21 +167,45 @@
|
||||
- (void)setPorpertyKeys:(NSArray *)propertyKeys forClass:(Class)c
|
||||
{
|
||||
if (propertyKeys.count == 0) return;
|
||||
self.propertyKeysDict[NSStringFromClass(c)] = propertyKeys;
|
||||
NSString *key = NSStringFromClass(c);
|
||||
if (!key) return;
|
||||
|
||||
MJ_LOCK(self.propertyKeysLock);
|
||||
self.propertyKeysDict[key] = propertyKeys;
|
||||
MJ_UNLOCK(self.propertyKeysLock);
|
||||
}
|
||||
|
||||
- (NSArray *)propertyKeysForClass:(Class)c
|
||||
{
|
||||
return self.propertyKeysDict[NSStringFromClass(c)];
|
||||
NSString *key = NSStringFromClass(c);
|
||||
if (!key) return nil;
|
||||
|
||||
MJ_LOCK(self.propertyKeysLock);
|
||||
NSArray *propertyKeys = self.propertyKeysDict[key];
|
||||
MJ_UNLOCK(self.propertyKeysLock);
|
||||
return propertyKeys;
|
||||
}
|
||||
|
||||
/** 模型数组中的模型类型 */
|
||||
- (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c
|
||||
{
|
||||
if (!objectClass) return;
|
||||
self.objectClassInArrayDict[NSStringFromClass(c)] = objectClass;
|
||||
NSString *key = NSStringFromClass(c);
|
||||
if (!key) return;
|
||||
|
||||
MJ_LOCK(self.objectClassInArrayLock);
|
||||
self.objectClassInArrayDict[key] = objectClass;
|
||||
MJ_UNLOCK(self.objectClassInArrayLock);
|
||||
}
|
||||
|
||||
- (Class)objectClassInArrayForClass:(Class)c
|
||||
{
|
||||
return self.objectClassInArrayDict[NSStringFromClass(c)];
|
||||
NSString *key = NSStringFromClass(c);
|
||||
if (!key) return nil;
|
||||
|
||||
MJ_LOCK(self.objectClassInArrayLock);
|
||||
Class objectClass = self.objectClassInArrayDict[key];
|
||||
MJ_UNLOCK(self.objectClassInArrayLock);
|
||||
return objectClass;
|
||||
}
|
||||
@end
|
||||
|
||||
Regular → Executable
Regular → Executable
@@ -13,24 +13,23 @@
|
||||
|
||||
@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];
|
||||
});
|
||||
|
||||
MJPropertyType *type = types[code];
|
||||
if (type == nil) {
|
||||
type = [[self alloc] init];
|
||||
type.code = code;
|
||||
types[code] = type;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
|
||||
Regular → Executable
+5
-5
@@ -14,14 +14,14 @@
|
||||
typedef void (^MJClassesEnumeration)(Class c, BOOL *stop);
|
||||
|
||||
/** 这个数组中的属性名才会进行字典和模型的转换 */
|
||||
typedef NSArray * (^MJAllowedPropertyNames)();
|
||||
typedef NSArray * (^MJAllowedPropertyNames)(void);
|
||||
/** 这个数组中的属性名才会进行归档 */
|
||||
typedef NSArray * (^MJAllowedCodingPropertyNames)();
|
||||
typedef NSArray * (^MJAllowedCodingPropertyNames)(void);
|
||||
|
||||
/** 这个数组中的属性名将会被忽略:不进行字典和模型的转换 */
|
||||
typedef NSArray * (^MJIgnoredPropertyNames)();
|
||||
typedef NSArray * (^MJIgnoredPropertyNames)(void);
|
||||
/** 这个数组中的属性名将会被忽略:不进行归档 */
|
||||
typedef NSArray * (^MJIgnoredCodingPropertyNames)();
|
||||
typedef NSArray * (^MJIgnoredCodingPropertyNames)(void);
|
||||
|
||||
/**
|
||||
* 类相关的扩展
|
||||
@@ -86,5 +86,5 @@ typedef NSArray * (^MJIgnoredCodingPropertyNames)();
|
||||
+ (NSMutableArray *)mj_totalIgnoredCodingPropertyNames;
|
||||
|
||||
#pragma mark - 内部使用
|
||||
+ (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key;
|
||||
+ (void)mj_setupBlockReturnValue:(id (^)(void))block key:(const char *)key;
|
||||
@end
|
||||
|
||||
Regular → Executable
+43
-38
@@ -17,30 +17,28 @@ static const char MJIgnoredPropertyNamesKey = '\0';
|
||||
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
|
||||
+ (NSMutableDictionary *)mj_classDictForKey:(const void *)key
|
||||
{
|
||||
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,8 +128,9 @@ static NSMutableDictionary *ignoredCodingPropertyNamesDict_;
|
||||
{
|
||||
return [self mj_totalObjectsWithSelector:@selector(mj_allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey];
|
||||
}
|
||||
|
||||
#pragma mark - block和方法处理:存储block的返回值
|
||||
+ (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key
|
||||
+ (void)mj_setupBlockReturnValue:(id (^)(void))block key:(const char *)key
|
||||
{
|
||||
if (block) {
|
||||
objc_setAssociatedObject(self, key, block(), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
@@ -140,31 +139,37 @@ static NSMutableDictionary *ignoredCodingPropertyNamesDict_;
|
||||
}
|
||||
|
||||
// 清空数据
|
||||
[[self dictForKey:key] removeAllObjects];
|
||||
MJExtensionSemaphoreCreate
|
||||
MJExtensionSemaphoreWait
|
||||
[[self mj_classDictForKey:key] removeAllObjects];
|
||||
MJExtensionSemaphoreSignal
|
||||
}
|
||||
|
||||
+ (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];
|
||||
|
||||
if ([self respondsToSelector:selector]) {
|
||||
MJExtensionSemaphoreCreate
|
||||
MJExtensionSemaphoreWait
|
||||
NSMutableArray *array = [self mj_classDictForKey:key][NSStringFromClass(self)];
|
||||
if (array == nil) {
|
||||
// 创建、存储
|
||||
[self mj_classDictForKey: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];
|
||||
NSArray *subArray = [self performSelector:selector];
|
||||
#pragma clang diagnostic pop
|
||||
if (subArray) {
|
||||
[array addObjectsFromArray:subArray];
|
||||
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
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
*/
|
||||
+ (NSDictionary *)mj_objectClassInArray;
|
||||
|
||||
|
||||
/** 特殊地区在字符串格式化数字时使用 */
|
||||
+ (NSLocale *)mj_numberLocale;
|
||||
|
||||
/**
|
||||
* 旧值换新值,用于过滤字典中的值
|
||||
*
|
||||
@@ -59,12 +63,16 @@
|
||||
/**
|
||||
* 当字典转模型完毕时调用
|
||||
*/
|
||||
- (void)mj_keyValuesDidFinishConvertingToObject;
|
||||
- (void)mj_keyValuesDidFinishConvertingToObject MJExtensionDeprecated("请使用`mj_didConvertToObjectWithKeyValues:`替代");
|
||||
- (void)mj_keyValuesDidFinishConvertingToObject:(NSDictionary *)keyValues MJExtensionDeprecated("请使用`mj_didConvertToObjectWithKeyValues:`替代");
|
||||
- (void)mj_didConvertToObjectWithKeyValues:(NSDictionary *)keyValues;
|
||||
|
||||
/**
|
||||
* 当模型转字典完毕时调用
|
||||
*/
|
||||
- (void)mj_objectDidFinishConvertingToKeyValues;
|
||||
- (void)mj_objectDidFinishConvertingToKeyValues MJExtensionDeprecated("请使用`mj_objectDidConvertToKeyValues:`替代");
|
||||
- (void)mj_objectDidConvertToKeyValues:(NSDictionary *)keyValues;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSObject (MJKeyValue) <MJKeyValue>
|
||||
@@ -184,42 +192,3 @@
|
||||
*/
|
||||
- (NSString *)mj_JSONString;
|
||||
@end
|
||||
|
||||
@interface NSObject (MJKeyValueDeprecated_v_2_5_16)
|
||||
- (instancetype)setKeyValues:(id)keyValue MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (instancetype)setKeyValues:(id)keyValues error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (void)referenceReplacedKeyWhenCreatingKeyValues:(BOOL)reference MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSMutableDictionary *)keyValues MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSMutableDictionary *)keyValuesWithError:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithFilename:(NSString *)filename MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithFilename:(NSString *)filename error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithFile:(NSString *)file MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (instancetype)objectWithFile:(NSString *)file error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithFilename:(NSString *)filename MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithFilename:(NSString *)filename error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithFile:(NSString *)file MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError **)error MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSData *)JSONData MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (id)JSONObject MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSString *)JSONString MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
@end
|
||||
|
||||
@@ -16,6 +16,26 @@
|
||||
#import "NSString+MJExtension.h"
|
||||
#import "NSObject+MJClass.h"
|
||||
|
||||
@implementation NSDecimalNumber(MJKeyValue)
|
||||
|
||||
- (id)standardValueWithTypeCode:(NSString *)typeCode {
|
||||
// 由于这里涉及到编译器问题, 暂时保留 Long, 实际上在 64 位系统上, 这 2 个精度范围相同,
|
||||
// 32 位略有不同, 其余都可使用 Double 进行强转不丢失精度
|
||||
if ([typeCode isEqualToString:MJPropertyTypeLongLong]) {
|
||||
return @(self.longLongValue);
|
||||
} else if ([typeCode isEqualToString:MJPropertyTypeLongLong.uppercaseString]) {
|
||||
return @(self.unsignedLongLongValue);
|
||||
} else if ([typeCode isEqualToString:MJPropertyTypeLong]) {
|
||||
return @(self.longValue);
|
||||
} else if ([typeCode isEqualToString:MJPropertyTypeLong.uppercaseString]) {
|
||||
return @(self.unsignedLongValue);
|
||||
} else {
|
||||
return @(self.doubleValue);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSObject (MJKeyValue)
|
||||
|
||||
#pragma mark - 错误
|
||||
@@ -53,11 +73,8 @@ static const char MJReferenceReplacedKeyWhenCreatingKeyValuesKey = '\0';
|
||||
}
|
||||
|
||||
#pragma mark - --常用的对象--
|
||||
static NSNumberFormatter *numberFormatter_;
|
||||
+ (void)load
|
||||
{
|
||||
numberFormatter_ = [[NSNumberFormatter alloc] init];
|
||||
|
||||
// 默认设置
|
||||
[self mj_referenceReplacedKeyWhenCreatingKeyValues:YES];
|
||||
}
|
||||
@@ -83,6 +100,11 @@ static NSNumberFormatter *numberFormatter_;
|
||||
NSArray *allowedPropertyNames = [clazz mj_totalAllowedPropertyNames];
|
||||
NSArray *ignoredPropertyNames = [clazz mj_totalIgnoredPropertyNames];
|
||||
|
||||
NSLocale *numberLocale = nil;
|
||||
if ([self.class respondsToSelector:@selector(mj_numberLocale)]) {
|
||||
numberLocale = self.class.mj_numberLocale;
|
||||
}
|
||||
|
||||
//通过封装的方法回调一个通过运行时编写的,用于返回属性列表的方法。
|
||||
[clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
|
||||
@try {
|
||||
@@ -141,50 +163,59 @@ static NSNumberFormatter *numberFormatter_;
|
||||
} else { // 字典数组-->模型数组
|
||||
value = [objectClass mj_objectArrayWithKeyValuesArray:value context:context];
|
||||
}
|
||||
} else {
|
||||
if (propertyClass == [NSString class]) {
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
// NSNumber -> NSString
|
||||
value = [value description];
|
||||
} else if ([value isKindOfClass:[NSURL class]]) {
|
||||
// NSURL -> NSString
|
||||
value = [value absoluteString];
|
||||
} else if (propertyClass == [NSString class]) {
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
// NSNumber -> NSString
|
||||
value = [value description];
|
||||
} else if ([value isKindOfClass:[NSURL class]]) {
|
||||
// NSURL -> NSString
|
||||
value = [value absoluteString];
|
||||
}
|
||||
} else if ([value isKindOfClass:[NSString class]]) {
|
||||
if (propertyClass == [NSURL class]) {
|
||||
// NSString -> NSURL
|
||||
// 字符串转码
|
||||
value = [value mj_url];
|
||||
} else if (type.isNumberType) {
|
||||
NSString *oldValue = value;
|
||||
|
||||
// NSString -> NSDecimalNumber, 使用 DecimalNumber 来转换数字, 避免丢失精度以及溢出
|
||||
NSDecimalNumber *decimalValue = [NSDecimalNumber decimalNumberWithString:oldValue
|
||||
locale:numberLocale];
|
||||
|
||||
// 检查特殊情况
|
||||
if (decimalValue == NSDecimalNumber.notANumber) {
|
||||
value = @(0);
|
||||
}else if (propertyClass != [NSDecimalNumber class]) {
|
||||
value = [decimalValue standardValueWithTypeCode:type.code];
|
||||
} else {
|
||||
value = decimalValue;
|
||||
}
|
||||
} else if ([value isKindOfClass:[NSString class]]) {
|
||||
if (propertyClass == [NSURL class]) {
|
||||
// NSString -> NSURL
|
||||
// 字符串转码
|
||||
value = [value mj_url];
|
||||
} else if (type.isNumberType) {
|
||||
NSString *oldValue = value;
|
||||
|
||||
// NSString -> NSNumber
|
||||
if (type.typeClass == [NSDecimalNumber class]) {
|
||||
value = [NSDecimalNumber decimalNumberWithString:oldValue];
|
||||
} else {
|
||||
value = [numberFormatter_ numberFromString:oldValue];
|
||||
}
|
||||
|
||||
// 如果是BOOL
|
||||
if (type.isBoolType) {
|
||||
// 字符串转BOOL(字符串没有charValue方法)
|
||||
// 系统会调用字符串的charValue转为BOOL类型
|
||||
NSString *lower = [oldValue lowercaseString];
|
||||
if ([lower isEqualToString:@"yes"] || [lower isEqualToString:@"true"]) {
|
||||
value = @YES;
|
||||
} else if ([lower isEqualToString:@"no"] || [lower isEqualToString:@"false"]) {
|
||||
value = @NO;
|
||||
}
|
||||
|
||||
// 如果是BOOL
|
||||
if (type.isBoolType) {
|
||||
// 字符串转BOOL(字符串没有charValue方法)
|
||||
// 系统会调用字符串的charValue转为BOOL类型
|
||||
NSString *lower = [oldValue lowercaseString];
|
||||
if ([lower isEqualToString:@"yes"] || [lower isEqualToString:@"true"]) {
|
||||
value = @YES;
|
||||
} else if ([lower isEqualToString:@"no"] || [lower isEqualToString:@"false"]) {
|
||||
value = @NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// value和property类型不匹配
|
||||
if (propertyClass && ![value isKindOfClass:propertyClass]) {
|
||||
value = nil;
|
||||
} else if ([value isKindOfClass:[NSNumber class]] && propertyClass == [NSDecimalNumber class]){
|
||||
// 过滤 NSDecimalNumber类型
|
||||
if (![value isKindOfClass:[NSDecimalNumber class]]) {
|
||||
value = [NSDecimalNumber decimalNumberWithDecimal:[((NSNumber *)value) decimalValue]];
|
||||
}
|
||||
}
|
||||
|
||||
// 经过转换后, 最终检查 value 与 property 是否匹配
|
||||
if (propertyClass && ![value isKindOfClass:propertyClass]) {
|
||||
value = nil;
|
||||
}
|
||||
|
||||
// 3.赋值
|
||||
[property setValue:value forObject:self];
|
||||
} @catch (NSException *exception) {
|
||||
@@ -194,9 +225,18 @@ static NSNumberFormatter *numberFormatter_;
|
||||
}];
|
||||
|
||||
// 转换完毕
|
||||
if ([self respondsToSelector:@selector(mj_didConvertToObjectWithKeyValues:)]) {
|
||||
[self mj_didConvertToObjectWithKeyValues:keyValues];
|
||||
}
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||
if ([self respondsToSelector:@selector(mj_keyValuesDidFinishConvertingToObject)]) {
|
||||
[self mj_keyValuesDidFinishConvertingToObject];
|
||||
}
|
||||
if ([self respondsToSelector:@selector(mj_keyValuesDidFinishConvertingToObject:)]) {
|
||||
[self mj_keyValuesDidFinishConvertingToObject:keyValues];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -299,6 +339,11 @@ static NSNumberFormatter *numberFormatter_;
|
||||
- (NSMutableDictionary *)mj_keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys
|
||||
{
|
||||
// 如果自己不是模型类, 那就返回自己
|
||||
// 模型类过滤掉 NSNull
|
||||
// 唯一一个不返回自己的
|
||||
if ([self isMemberOfClass:NSNull.class]) { return nil; }
|
||||
// 这里虽然返回了自己, 但是其实是有报错信息的.
|
||||
// TODO: 报错机制不好, 需要重做
|
||||
MJExtensionAssertError(![MJFoundation isClassFromFoundation:[self class]], (NSMutableDictionary *)self, [self class], @"不是自定义的模型类")
|
||||
|
||||
id keyValues = [NSMutableDictionary dictionary];
|
||||
@@ -387,9 +432,15 @@ static NSNumberFormatter *numberFormatter_;
|
||||
}];
|
||||
|
||||
// 转换完毕
|
||||
if ([self respondsToSelector:@selector(mj_objectDidConvertToKeyValues:)]) {
|
||||
[self mj_objectDidConvertToKeyValues:keyValues];
|
||||
}
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||
if ([self respondsToSelector:@selector(mj_objectDidFinishConvertingToKeyValues)]) {
|
||||
[self mj_objectDidFinishConvertingToKeyValues];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
return keyValues;
|
||||
}
|
||||
@@ -418,9 +469,13 @@ static NSNumberFormatter *numberFormatter_;
|
||||
NSMutableArray *keyValuesArray = [NSMutableArray array];
|
||||
for (id object in objectArray) {
|
||||
if (keys) {
|
||||
[keyValuesArray addObject:[object mj_keyValuesWithKeys:keys]];
|
||||
id convertedObj = [object mj_keyValuesWithKeys:keys];
|
||||
if (!convertedObj) { continue; }
|
||||
[keyValuesArray addObject:convertedObj];
|
||||
} else {
|
||||
[keyValuesArray addObject:[object mj_keyValuesWithIgnoredKeys:ignoredKeys]];
|
||||
id convertedObj = [object mj_keyValuesWithIgnoredKeys:ignoredKeys];
|
||||
if (!convertedObj) { continue; }
|
||||
[keyValuesArray addObject:convertedObj];
|
||||
}
|
||||
}
|
||||
return keyValuesArray;
|
||||
@@ -459,251 +514,5 @@ static NSNumberFormatter *numberFormatter_;
|
||||
|
||||
return [[NSString alloc] initWithData:[self mj_JSONData] encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSObject (MJKeyValueDeprecated_v_2_5_16)
|
||||
- (instancetype)setKeyValues:(id)keyValues
|
||||
{
|
||||
return [self mj_setKeyValues:keyValues];
|
||||
}
|
||||
|
||||
- (instancetype)setKeyValues:(id)keyValues error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_setKeyValues:keyValues];
|
||||
if (error != NULL) {
|
||||
*error = [self.class mj_error];
|
||||
}
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
- (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
|
||||
{
|
||||
return [self mj_setKeyValues:keyValues context:context];
|
||||
}
|
||||
|
||||
- (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_setKeyValues:keyValues context:context];
|
||||
if (error != NULL) {
|
||||
*error = [self.class mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (void)referenceReplacedKeyWhenCreatingKeyValues:(BOOL)reference
|
||||
{
|
||||
[self mj_referenceReplacedKeyWhenCreatingKeyValues:reference];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)keyValues
|
||||
{
|
||||
return [self mj_keyValues];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)keyValuesWithError:(NSError **)error
|
||||
{
|
||||
id value = [self mj_keyValues];
|
||||
if (error != NULL) {
|
||||
*error = [self.class mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys
|
||||
{
|
||||
return [self mj_keyValuesWithKeys:keys];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_keyValuesWithKeys:keys];
|
||||
if (error != NULL) {
|
||||
*error = [self.class mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys
|
||||
{
|
||||
return [self mj_keyValuesWithIgnoredKeys:ignoredKeys];
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_keyValuesWithIgnoredKeys:ignoredKeys];
|
||||
if (error != NULL) {
|
||||
*error = [self.class mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray
|
||||
{
|
||||
return [self mj_keyValuesArrayWithObjectArray:objectArray];
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_keyValuesArrayWithObjectArray:objectArray];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys
|
||||
{
|
||||
return [self mj_keyValuesArrayWithObjectArray:objectArray keys:keys];
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_keyValuesArrayWithObjectArray:objectArray keys:keys];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys
|
||||
{
|
||||
return [self mj_keyValuesArrayWithObjectArray:objectArray ignoredKeys:ignoredKeys];
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_keyValuesArrayWithObjectArray:objectArray ignoredKeys:ignoredKeys];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues
|
||||
{
|
||||
return [self mj_objectWithKeyValues:keyValues];
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectWithKeyValues:keyValues];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
|
||||
{
|
||||
return [self mj_objectWithKeyValues:keyValues context:context];
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectWithKeyValues:keyValues context:context];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithFilename:(NSString *)filename
|
||||
{
|
||||
return [self mj_objectWithFilename:filename];
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithFilename:(NSString *)filename error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectWithFilename:filename];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithFile:(NSString *)file
|
||||
{
|
||||
return [self mj_objectWithFile:file];
|
||||
}
|
||||
|
||||
+ (instancetype)objectWithFile:(NSString *)file error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectWithFile:file];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray
|
||||
{
|
||||
return [self mj_objectArrayWithKeyValuesArray:keyValuesArray];
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectArrayWithKeyValuesArray:keyValuesArray];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context
|
||||
{
|
||||
return [self mj_objectArrayWithKeyValuesArray:keyValuesArray context:context];
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectArrayWithKeyValuesArray:keyValuesArray context:context];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithFilename:(NSString *)filename
|
||||
{
|
||||
return [self mj_objectArrayWithFilename:filename];
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithFilename:(NSString *)filename error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectArrayWithFilename:filename];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithFile:(NSString *)file
|
||||
{
|
||||
return [self mj_objectArrayWithFile:file];
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError **)error
|
||||
{
|
||||
id value = [self mj_objectArrayWithFile:file];
|
||||
if (error != NULL) {
|
||||
*error = [self mj_error];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSData *)JSONData
|
||||
{
|
||||
return [self mj_JSONData];
|
||||
}
|
||||
|
||||
- (id)JSONObject
|
||||
{
|
||||
return [self mj_JSONObject];
|
||||
}
|
||||
|
||||
- (NSString *)JSONString
|
||||
{
|
||||
return [self mj_JSONString];
|
||||
}
|
||||
@end
|
||||
Regular → Executable
+2
-11
@@ -20,10 +20,10 @@
|
||||
typedef void (^MJPropertiesEnumeration)(MJProperty *property, BOOL *stop);
|
||||
|
||||
/** 将属性名换为其他key去字典中取值 */
|
||||
typedef NSDictionary * (^MJReplacedKeyFromPropertyName)();
|
||||
typedef NSDictionary * (^MJReplacedKeyFromPropertyName)(void);
|
||||
typedef id (^MJReplacedKeyFromPropertyName121)(NSString *propertyName);
|
||||
/** 数组中需要转换的模型类 */
|
||||
typedef NSDictionary * (^MJObjectClassInArray)();
|
||||
typedef NSDictionary * (^MJObjectClassInArray)(void);
|
||||
/** 用于过滤字典中的值 */
|
||||
typedef id (^MJNewValueFromOldValue)(id object, id oldValue, MJProperty *property);
|
||||
|
||||
@@ -68,12 +68,3 @@ typedef id (^MJNewValueFromOldValue)(id object, id oldValue, MJProperty *propert
|
||||
*/
|
||||
+ (void)mj_setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray;
|
||||
@end
|
||||
|
||||
@interface NSObject (MJPropertyDeprecated_v_2_5_16)
|
||||
+ (void)enumerateProperties:(MJPropertiesEnumeration)enumeration MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (void)setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (id)getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(__unsafe_unretained MJProperty *)property MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (void)setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (void)setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121 MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
+ (void)setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
@end
|
||||
Regular → Executable
+69
-104
@@ -27,35 +27,33 @@ static const char MJCachedPropertiesKey = '\0';
|
||||
|
||||
@implementation NSObject (Property)
|
||||
|
||||
static NSMutableDictionary *replacedKeyFromPropertyNameDict_;
|
||||
static NSMutableDictionary *replacedKeyFromPropertyName121Dict_;
|
||||
static NSMutableDictionary *newValueFromOldValueDict_;
|
||||
static NSMutableDictionary *objectClassInArrayDict_;
|
||||
static NSMutableDictionary *cachedPropertiesDict_;
|
||||
|
||||
+ (void)load
|
||||
+ (NSMutableDictionary *)mj_propertyDictForKey:(const void *)key
|
||||
{
|
||||
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 - --私有方法--
|
||||
+ (id)propertyKey:(NSString *)propertyName
|
||||
+ (id)mj_propertyKey:(NSString *)propertyName
|
||||
{
|
||||
MJExtensionAssertParamNotNil2(propertyName, nil);
|
||||
|
||||
@@ -64,10 +62,6 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
if ([self respondsToSelector:@selector(mj_replacedKeyFromPropertyName121:)]) {
|
||||
key = [self mj_replacedKeyFromPropertyName121:propertyName];
|
||||
}
|
||||
// 兼容旧版本
|
||||
if ([self respondsToSelector:@selector(replacedKeyFromPropertyName121:)]) {
|
||||
key = [self performSelector:@selector(replacedKeyFromPropertyName121) withObject:propertyName];
|
||||
}
|
||||
|
||||
// 调用block
|
||||
if (!key) {
|
||||
@@ -84,10 +78,6 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
if ((!key || [key isEqual:propertyName]) && [self respondsToSelector:@selector(mj_replacedKeyFromPropertyName)]) {
|
||||
key = [self mj_replacedKeyFromPropertyName][propertyName];
|
||||
}
|
||||
// 兼容旧版本
|
||||
if ((!key || [key isEqual:propertyName]) && [self respondsToSelector:@selector(replacedKeyFromPropertyName)]) {
|
||||
key = [self performSelector:@selector(replacedKeyFromPropertyName)][propertyName];
|
||||
}
|
||||
|
||||
if (!key || [key isEqual:propertyName]) {
|
||||
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
|
||||
@@ -105,16 +95,12 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
return key;
|
||||
}
|
||||
|
||||
+ (Class)propertyObjectClassInArray:(NSString *)propertyName
|
||||
+ (Class)mj_propertyObjectClassInArray:(NSString *)propertyName
|
||||
{
|
||||
__block id clazz = nil;
|
||||
if ([self respondsToSelector:@selector(mj_objectClassInArray)]) {
|
||||
clazz = [self mj_objectClassInArray][propertyName];
|
||||
}
|
||||
// 兼容旧版本
|
||||
if ([self respondsToSelector:@selector(objectClassInArray)]) {
|
||||
clazz = [self performSelector:@selector(objectClassInArray)][propertyName];
|
||||
}
|
||||
|
||||
if (!clazz) {
|
||||
[self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
|
||||
@@ -137,8 +123,10 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
+ (void)mj_enumerateProperties:(MJPropertiesEnumeration)enumeration
|
||||
{
|
||||
// 获得成员变量
|
||||
NSArray *cachedProperties = [self properties];
|
||||
|
||||
MJExtensionSemaphoreCreate
|
||||
MJExtensionSemaphoreWait
|
||||
NSArray *cachedProperties = [self mj_properties];
|
||||
MJExtensionSemaphoreSignal
|
||||
// 遍历成员变量
|
||||
BOOL stop = NO;
|
||||
for (MJProperty *property in cachedProperties) {
|
||||
@@ -148,34 +136,39 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
+ (NSMutableArray *)properties
|
||||
+ (NSMutableArray *)mj_properties
|
||||
{
|
||||
NSMutableArray *cachedProperties = [self dictForKey:&MJCachedPropertiesKey][NSStringFromClass(self)];
|
||||
|
||||
NSMutableArray *cachedProperties = [self mj_propertyDictForKey:&MJCachedPropertiesKey][NSStringFromClass(self)];
|
||||
if (cachedProperties == nil) {
|
||||
cachedProperties = [NSMutableArray array];
|
||||
|
||||
[self mj_enumerateClasses:^(__unsafe_unretained Class c, BOOL *stop) {
|
||||
// 1.获得所有的成员变量
|
||||
unsigned int outCount = 0;
|
||||
objc_property_t *properties = class_copyPropertyList(c, &outCount);
|
||||
|
||||
if (cachedProperties == nil) {
|
||||
cachedProperties = [NSMutableArray array];
|
||||
|
||||
// 2.遍历每一个成员变量
|
||||
for (unsigned int i = 0; i<outCount; i++) {
|
||||
MJProperty *property = [MJProperty cachedPropertyWithProperty:properties[i]];
|
||||
// 过滤掉Foundation框架类里面的属性
|
||||
if ([MJFoundation isClassFromFoundation:property.srcClass]) continue;
|
||||
property.srcClass = c;
|
||||
[property setOriginKey:[self propertyKey:property.name] forClass:self];
|
||||
[property setObjectClassInArray:[self propertyObjectClassInArray:property.name] forClass:self];
|
||||
[cachedProperties addObject:property];
|
||||
}
|
||||
[self mj_enumerateClasses:^(__unsafe_unretained Class c, BOOL *stop) {
|
||||
// 1.获得所有的成员变量
|
||||
unsigned int outCount = 0;
|
||||
objc_property_t *properties = class_copyPropertyList(c, &outCount);
|
||||
|
||||
// 2.遍历每一个成员变量
|
||||
for (unsigned int i = 0; i<outCount; i++) {
|
||||
MJProperty *property = [MJProperty cachedPropertyWithProperty:properties[i]];
|
||||
// 过滤掉Foundation框架类里面的属性
|
||||
if ([MJFoundation isClassFromFoundation:property.srcClass]) continue;
|
||||
// 过滤掉`hash`, `superclass`, `description`, `debugDescription`
|
||||
if ([MJFoundation isFromNSObjectProtocolProperty:property.name]) continue;
|
||||
|
||||
property.srcClass = c;
|
||||
[property setOriginKey:[self mj_propertyKey:property.name] forClass:self];
|
||||
[property setObjectClassInArray:[self mj_propertyObjectClassInArray:property.name] forClass:self];
|
||||
[cachedProperties addObject:property];
|
||||
}
|
||||
|
||||
// 3.释放内存
|
||||
free(properties);
|
||||
}];
|
||||
|
||||
// 3.释放内存
|
||||
free(properties);
|
||||
}];
|
||||
|
||||
[self dictForKey:&MJCachedPropertiesKey][NSStringFromClass(self)] = cachedProperties;
|
||||
[self mj_propertyDictForKey:&MJCachedPropertiesKey][NSStringFromClass(self)] = cachedProperties;
|
||||
}
|
||||
}
|
||||
|
||||
return cachedProperties;
|
||||
@@ -192,10 +185,6 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
if ([object respondsToSelector:@selector(mj_newValueFromOldValue:property:)]) {
|
||||
return [object mj_newValueFromOldValue:oldValue property:property];
|
||||
}
|
||||
// 兼容旧版本
|
||||
if ([self respondsToSelector:@selector(newValueFromOldValue:property:)]) {
|
||||
return [self performSelector:@selector(newValueFromOldValue:property:) withObject:oldValue withObject:property];
|
||||
}
|
||||
|
||||
// 查看静态设置
|
||||
__block id newValue = oldValue;
|
||||
@@ -214,7 +203,10 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
{
|
||||
[self mj_setupBlockReturnValue:objectClassInArray key:&MJObjectClassInArrayKey];
|
||||
|
||||
[[self dictForKey:&MJCachedPropertiesKey] removeAllObjects];
|
||||
MJExtensionSemaphoreCreate
|
||||
MJExtensionSemaphoreWait
|
||||
[[self mj_propertyDictForKey:&MJCachedPropertiesKey] removeAllObjects];
|
||||
MJExtensionSemaphoreSignal
|
||||
}
|
||||
|
||||
#pragma mark - key配置
|
||||
@@ -222,47 +214,20 @@ static NSMutableDictionary *cachedPropertiesDict_;
|
||||
{
|
||||
[self mj_setupBlockReturnValue:replacedKeyFromPropertyName key:&MJReplacedKeyFromPropertyNameKey];
|
||||
|
||||
[[self dictForKey:&MJCachedPropertiesKey] removeAllObjects];
|
||||
MJExtensionSemaphoreCreate
|
||||
MJExtensionSemaphoreWait
|
||||
[[self mj_propertyDictForKey:&MJCachedPropertiesKey] removeAllObjects];
|
||||
MJExtensionSemaphoreSignal
|
||||
}
|
||||
|
||||
+ (void)mj_setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121
|
||||
{
|
||||
objc_setAssociatedObject(self, &MJReplacedKeyFromPropertyName121Key, replacedKeyFromPropertyName121, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
|
||||
[[self dictForKey:&MJCachedPropertiesKey] removeAllObjects];
|
||||
MJExtensionSemaphoreCreate
|
||||
MJExtensionSemaphoreWait
|
||||
[[self mj_propertyDictForKey:&MJCachedPropertiesKey] removeAllObjects];
|
||||
MJExtensionSemaphoreSignal
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSObject (MJPropertyDeprecated_v_2_5_16)
|
||||
+ (void)enumerateProperties:(MJPropertiesEnumeration)enumeration
|
||||
{
|
||||
[self mj_enumerateProperties:enumeration];
|
||||
}
|
||||
|
||||
+ (void)setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue
|
||||
{
|
||||
[self mj_setupNewValueFromOldValue:newValueFormOldValue];
|
||||
}
|
||||
|
||||
+ (id)getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(__unsafe_unretained MJProperty *)property
|
||||
{
|
||||
return [self mj_getNewValueFromObject:object oldValue:oldValue property:property];
|
||||
}
|
||||
|
||||
+ (void)setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName
|
||||
{
|
||||
[self mj_setupReplacedKeyFromPropertyName:replacedKeyFromPropertyName];
|
||||
}
|
||||
|
||||
+ (void)setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121
|
||||
{
|
||||
[self mj_setupReplacedKeyFromPropertyName121:replacedKeyFromPropertyName121];
|
||||
}
|
||||
|
||||
+ (void)setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray
|
||||
{
|
||||
[self mj_setupObjectClassInArray:objectClassInArray];
|
||||
}
|
||||
@end
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
Regular → Executable
-9
@@ -31,12 +31,3 @@
|
||||
|
||||
- (NSURL *)mj_url;
|
||||
@end
|
||||
|
||||
@interface NSString (MJExtensionDeprecated_v_2_5_16)
|
||||
- (NSString *)underlineFromCamel MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSString *)camelFromUnderline MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSString *)firstCharUpper MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSString *)firstCharLower MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (BOOL)isPureInt MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
- (NSURL *)url MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
|
||||
@end
|
||||
|
||||
Regular → Executable
-32
@@ -78,35 +78,3 @@
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSString (MJExtensionDeprecated_v_2_5_16)
|
||||
- (NSString *)underlineFromCamel
|
||||
{
|
||||
return self.mj_underlineFromCamel;
|
||||
}
|
||||
|
||||
- (NSString *)camelFromUnderline
|
||||
{
|
||||
return self.mj_camelFromUnderline;
|
||||
}
|
||||
|
||||
- (NSString *)firstCharLower
|
||||
{
|
||||
return self.mj_firstCharLower;
|
||||
}
|
||||
|
||||
- (NSString *)firstCharUpper
|
||||
{
|
||||
return self.mj_firstCharUpper;
|
||||
}
|
||||
|
||||
- (BOOL)isPureInt
|
||||
{
|
||||
return self.mj_isPureInt;
|
||||
}
|
||||
|
||||
- (NSURL *)url
|
||||
{
|
||||
return self.mj_url;
|
||||
}
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user