Browse Source

fix potential problem when class updated

ibireme 9 years ago
parent
commit
95ca2731c0
3 changed files with 17 additions and 3 deletions
  1. 3 1
      YYModel/NSObject+YYModel.m
  2. 10 2
      YYModel/YYClassInfo.h
  3. 4 0
      YYModel/YYClassInfo.m

+ 3 - 1
YYModel/NSObject+YYModel.m

@@ -404,6 +404,7 @@ static force_inline id YYValueForMultiKeys(__unsafe_unretained NSDictionary *dic
 /// A class info in object model.
 /// A class info in object model.
 @interface _YYModelMeta : NSObject {
 @interface _YYModelMeta : NSObject {
     @package
     @package
+    YYClassInfo *_classInfo;
     /// Key:mapped key and key path, Value:_YYModelPropertyInfo.
     /// Key:mapped key and key path, Value:_YYModelPropertyInfo.
     NSDictionary *_mapper;
     NSDictionary *_mapper;
     /// Array<_YYModelPropertyMeta>, all property meta of this model.
     /// Array<_YYModelPropertyMeta>, all property meta of this model.
@@ -554,6 +555,7 @@ static force_inline id YYValueForMultiKeys(__unsafe_unretained NSDictionary *dic
     if (keyPathPropertyMetas) _keyPathPropertyMetas = keyPathPropertyMetas;
     if (keyPathPropertyMetas) _keyPathPropertyMetas = keyPathPropertyMetas;
     if (multiKeysPropertyMetas) _multiKeysPropertyMetas = multiKeysPropertyMetas;
     if (multiKeysPropertyMetas) _multiKeysPropertyMetas = multiKeysPropertyMetas;
     
     
+    _classInfo = classInfo;
     _keyMappedCount = _allPropertyMetas.count;
     _keyMappedCount = _allPropertyMetas.count;
     _nsType = YYClassGetNSType(cls);
     _nsType = YYClassGetNSType(cls);
     _hasCustomTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformFromDictionary:)]);
     _hasCustomTransformFromDictionary = ([cls instancesRespondToSelector:@selector(modelCustomTransformFromDictionary:)]);
@@ -576,7 +578,7 @@ static force_inline id YYValueForMultiKeys(__unsafe_unretained NSDictionary *dic
     dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
     dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
     _YYModelMeta *meta = CFDictionaryGetValue(cache, (__bridge const void *)(cls));
     _YYModelMeta *meta = CFDictionaryGetValue(cache, (__bridge const void *)(cls));
     dispatch_semaphore_signal(lock);
     dispatch_semaphore_signal(lock);
-    if (!meta) {
+    if (!meta || meta->_classInfo.needUpdate) {
         meta = [[_YYModelMeta alloc] initWithClass:cls];
         meta = [[_YYModelMeta alloc] initWithClass:cls];
         if (meta) {
         if (meta) {
             dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
             dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);

+ 10 - 2
YYModel/YYClassInfo.h

@@ -159,11 +159,19 @@ YYEncodingType YYEncodingGetType(const char *typeEncoding);
  If the class is changed (for example: you add a method to this class with
  If the class is changed (for example: you add a method to this class with
  'class_addMethod()'), you should call this method to refresh the class info cache.
  'class_addMethod()'), you should call this method to refresh the class info cache.
  
  
- After called this method, you may call 'classInfoWithClass' or 
- 'classInfoWithClassName' to get the updated class info.
+ After called this method, `needUpdate` will returns `YES`, and you should call 
+ 'classInfoWithClass' or 'classInfoWithClassName' to get the updated class info.
  */
  */
 - (void)setNeedUpdate;
 - (void)setNeedUpdate;
 
 
+/**
+ If this method returns `YES`, you should stop using this instance and call
+ `classInfoWithClass` or `classInfoWithClassName` to get the updated class info.
+ 
+ @return Whether this class info need update.
+ */
+- (BOOL)needUpdate;
+
 /**
 /**
  Get the class info of a specified Class.
  Get the class info of a specified Class.
  
  

+ 4 - 0
YYModel/YYClassInfo.m

@@ -308,6 +308,10 @@ YYEncodingType YYEncodingGetType(const char *typeEncoding) {
     _needUpdate = YES;
     _needUpdate = YES;
 }
 }
 
 
+- (BOOL)needUpdate {
+    return _needUpdate;
+}
+
 + (instancetype)classInfoWithClass:(Class)cls {
 + (instancetype)classInfoWithClass:(Class)cls {
     if (!cls) return nil;
     if (!cls) return nil;
     static CFMutableDictionaryRef classCache;
     static CFMutableDictionaryRef classCache;