From f187bf780d04734e0d2a4d652c51aa2efce2f18e Mon Sep 17 00:00:00 2001 From: libin14 <> Date: Tue, 20 Oct 2020 22:57:54 +0800 Subject: [PATCH 1/2] Fix config with inherited property bug --- MJExtension/NSObject+MJClass.m | 22 ++++++++++--------- MJExtensionDemo.xcodeproj/project.pbxproj | 12 ++++++++--- MJExtensionTests/MJExtensionTests.m | 13 ++++++++++++ MJExtensionTests/Model/MJElement.h | 26 +++++++++++++++++++++++ MJExtensionTests/Model/MJElement.m | 26 +++++++++++++++++++++++ 5 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 MJExtensionTests/Model/MJElement.h create mode 100644 MJExtensionTests/Model/MJElement.m diff --git a/MJExtension/NSObject+MJClass.m b/MJExtension/NSObject+MJClass.m index cd987cfe..4066cb80 100644 --- a/MJExtension/NSObject+MJClass.m +++ b/MJExtension/NSObject+MJClass.m @@ -145,26 +145,27 @@ + (void)mj_setupBlockReturnValue:(id (^)(void))block key:(const char *)key MJExtensionSemaphoreSignal } -+ (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *)key -{ ++ (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *)key { 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]) { + NSMutableSet *classMethodSets = NSMutableSet.set; + [self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) { + Method method = class_getClassMethod(c, selector); + NSString *methodAddress = [NSString stringWithFormat:@"%p", method]; + if (method && ![classMethodSets containsObject:methodAddress]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - NSArray *subArray = [self performSelector:selector]; + NSArray *subArray = [c performSelector:selector]; #pragma clang diagnostic pop - if (subArray) { - [array addObjectsFromArray:subArray]; + if (subArray) { + [array addObjectsFromArray:subArray]; + } + [classMethodSets addObject:methodAddress]; } - } - - [self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) { NSArray *subArray = objc_getAssociatedObject(c, key); [array addObjectsFromArray:subArray]; }]; @@ -172,4 +173,5 @@ + (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *) MJExtensionSemaphoreSignal return array; } + @end diff --git a/MJExtensionDemo.xcodeproj/project.pbxproj b/MJExtensionDemo.xcodeproj/project.pbxproj index 49c1c82f..3bc315de 100644 --- a/MJExtensionDemo.xcodeproj/project.pbxproj +++ b/MJExtensionDemo.xcodeproj/project.pbxproj @@ -53,6 +53,7 @@ 2D2DBA832317DBE0005A689E /* MJAd.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D2DBA732317DBDF005A689E /* MJAd.m */; }; 2D2DBA842317DBE0005A689E /* MJExtensionConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D2DBA752317DBDF005A689E /* MJExtensionConfig.m */; }; 2D2DBA852317DBE0005A689E /* MJPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D2DBA772317DBDF005A689E /* MJPerson.m */; }; + 6B431A1D253F2EA900F08763 /* MJElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B431A1C253F2EA900F08763 /* MJElement.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -155,6 +156,8 @@ 2D2DBA762317DBDF005A689E /* MJBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJBook.h; sourceTree = ""; }; 2D2DBA772317DBDF005A689E /* MJPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJPerson.m; sourceTree = ""; }; 2D2DBA872317DCCF005A689E /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; + 6B431A1B253F2EA900F08763 /* MJElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MJElement.h; sourceTree = ""; }; + 6B431A1C253F2EA900F08763 /* MJElement.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MJElement.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -289,18 +292,20 @@ 2D2DBA602317DBDF005A689E /* MJDog.m */, 2D2DBA6B2317DBDF005A689E /* MJExtensionConfig.h */, 2D2DBA752317DBDF005A689E /* MJExtensionConfig.m */, + 0130EE7E233C56D8008D2386 /* MJFrenchUser.h */, + 0130EE7F233C56D8008D2386 /* MJFrenchUser.m */, 2D2DBA682317DBDF005A689E /* MJPerson.h */, 2D2DBA772317DBDF005A689E /* MJPerson.m */, 2D2DBA622317DBDF005A689E /* MJStatus.h */, 2D2DBA722317DBDF005A689E /* MJStatus.m */, 2D2DBA642317DBDF005A689E /* MJStatusResult.h */, 2D2DBA712317DBDF005A689E /* MJStatusResult.m */, - 2D2DBA662317DBDF005A689E /* MJStudent.m */, 2D2DBA6F2317DBDF005A689E /* MJStudent.h */, + 2D2DBA662317DBDF005A689E /* MJStudent.m */, 2D2DBA672317DBDF005A689E /* MJUser.h */, 2D2DBA6E2317DBDF005A689E /* MJUser.m */, - 0130EE7E233C56D8008D2386 /* MJFrenchUser.h */, - 0130EE7F233C56D8008D2386 /* MJFrenchUser.m */, + 6B431A1B253F2EA900F08763 /* MJElement.h */, + 6B431A1C253F2EA900F08763 /* MJElement.m */, ); path = Model; sourceTree = ""; @@ -501,6 +506,7 @@ 2D2DBA842317DBE0005A689E /* MJExtensionConfig.m in Sources */, 2D2DBA7F2317DBE0005A689E /* MJBaseObject.m in Sources */, 2D2DBA7D2317DBE0005A689E /* MJBook.m in Sources */, + 6B431A1D253F2EA900F08763 /* MJElement.m in Sources */, 2D2DBA7A2317DBE0005A689E /* MJDog.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/MJExtensionTests/MJExtensionTests.m b/MJExtensionTests/MJExtensionTests.m index af49468f..4dbf6160 100644 --- a/MJExtensionTests/MJExtensionTests.m +++ b/MJExtensionTests/MJExtensionTests.m @@ -19,6 +19,7 @@ #import #import "MJFrenchUser.h" #import "MJCat.h" +#import "MJElement.h" @interface MJExtensionTests : XCTestCase @@ -525,4 +526,16 @@ - (void)testLogAllProperties { MJExtensionLog(@"%@", user); } + +#pragma mark 使用 mj_ignoredPropertyNames/mj_allowedPropertyNames 存在继承 +- (void)testIgnoredInheritedProperties { + NSDictionary *dict = @{ + @"count" : @"100", + @"renderName" : @"MJRenderElementName" + }; + MJRenderElement *renderElement = [MJRenderElement mj_objectWithKeyValues:dict]; + XCTAssert(renderElement.count == 0); + XCTAssertFalse(renderElement.renderName); +} + @end diff --git a/MJExtensionTests/Model/MJElement.h b/MJExtensionTests/Model/MJElement.h new file mode 100644 index 00000000..6048516c --- /dev/null +++ b/MJExtensionTests/Model/MJElement.h @@ -0,0 +1,26 @@ +// +// MJElement.h +// MJExtensionTests +// +// Created by libin14 on 2020/10/20. +// Copyright © 2020 MJ Lee. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MJElement : NSObject + +@property (assign, nonatomic) NSInteger count; + +@end + + +@interface MJRenderElement : MJElement + +@property (copy, nonatomic) NSString *renderName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MJExtensionTests/Model/MJElement.m b/MJExtensionTests/Model/MJElement.m new file mode 100644 index 00000000..29aaf083 --- /dev/null +++ b/MJExtensionTests/Model/MJElement.m @@ -0,0 +1,26 @@ +// +// MJElement.m +// MJExtensionTests +// +// Created by libin14 on 2020/10/20. +// Copyright © 2020 MJ Lee. All rights reserved. +// + +#import "MJElement.h" + +@implementation MJElement + ++ (NSArray *)mj_ignoredPropertyNames { + return @[@"count"]; +} + +@end + +@implementation MJRenderElement + ++ (NSArray *)mj_ignoredPropertyNames { + return @[@"renderName"]; +} + +@end + From 953ad76195bbdef59333460c74a0a4e702da8ae1 Mon Sep 17 00:00:00 2001 From: libin14 <> Date: Wed, 21 Oct 2020 09:46:23 +0800 Subject: [PATCH 2/2] method address change string to number --- MJExtension/NSObject+MJClass.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MJExtension/NSObject+MJClass.m b/MJExtension/NSObject+MJClass.m index 4066cb80..9ed7836a 100644 --- a/MJExtension/NSObject+MJClass.m +++ b/MJExtension/NSObject+MJClass.m @@ -155,7 +155,7 @@ + (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *) NSMutableSet *classMethodSets = NSMutableSet.set; [self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) { Method method = class_getClassMethod(c, selector); - NSString *methodAddress = [NSString stringWithFormat:@"%p", method]; + NSNumber *methodAddress = @((int64_t)(void *)method); if (method && ![classMethodSets containsObject:methodAddress]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks"