├── .gitignore ├── LcCategoryProperty ├── NSObject+LcInvokeAllMethod.h ├── NSObject+LcInvokeAllMethod.m ├── NSObject+LcProperty.h └── NSObject+LcProperty.m ├── LcCategoryPropertySample ├── LcCategoryPropertySample.xcodeproj │ └── project.pbxproj └── LcCategoryPropertySample │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── Model+Property.h │ ├── Model+Property.m │ ├── Model+second.h │ ├── Model+second.m │ ├── Model.h │ ├── Model.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | project.xcworkspace 2 | xcuserdata 3 | -------------------------------------------------------------------------------- /LcCategoryProperty/NSObject+LcInvokeAllMethod.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+LcInvokeAllMethod.h 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/22. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (LcInvokeAllMethod) 12 | 13 | /** 14 | * 通过selector调用所有实例的方法,包括被category覆盖的方法 15 | * @param selector 要调用方法的selector 16 | */ 17 | - (void)invokeAllInstanceMethodWithSelector:(SEL)selector; 18 | 19 | /** 20 | * 通过selector调用所有类的方法,包括被category覆盖的方法 21 | * @param selector 方法的selector 22 | */ 23 | + (void)invokeAllClassMethodWithSelector:(SEL)selector; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /LcCategoryProperty/NSObject+LcInvokeAllMethod.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+LcInvokeAllMethod.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/22. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "NSObject+LcInvokeAllMethod.h" 10 | #import 11 | 12 | @implementation NSObject (LcInvokeAllMethod) 13 | 14 | static inline void __invoke_all_method(id self, SEL selecotr) 15 | { 16 | //1. 根据self,获取class 17 | Class class = object_getClass(self); 18 | 19 | //2. 获取方法列表 20 | uint count; 21 | Method *methodList = class_copyMethodList(class, &count); 22 | 23 | //3. 遍历方法列表 24 | for (int i = 0; i < count; i++) { 25 | Method method = methodList[i]; 26 | //4. 根据SEL查找方法 27 | if (!sel_isEqual(selecotr, method_getName(method))) { 28 | continue; 29 | } 30 | 31 | //5. 获取方法的实现 32 | IMP implement = method_getImplementation(method); 33 | 34 | //6. 直接调用方法的实现 35 | ((void(*)(id,SEL))implement)(self, selecotr); 36 | } 37 | } 38 | 39 | - (void)invokeAllInstanceMethodWithSelector:(SEL)selector 40 | { 41 | __invoke_all_method(self, selector); 42 | } 43 | 44 | + (void)invokeAllClassMethodWithSelector:(SEL)selector 45 | { 46 | __invoke_all_method(self, selector); 47 | } 48 | 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /LcCategoryProperty/NSObject+LcProperty.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+LcProperty.h 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | extern NSString *LcAddPropertyException; 13 | 14 | @interface NSObject (LcProperty) 15 | /** 16 | * 为类添加id类型的属性,objc_AssociationPolicy类型为OBJC_ASSOCIATION_RETAIN_NONATOMIC 17 | * @param name 属性的name 18 | */ 19 | + (void)addObjectProperty:(NSString *)name; 20 | 21 | /** 22 | * 为类添加id类型的属性 23 | * @param name 属性的name 24 | * @param policy 属性的policy 25 | */ 26 | + (void)addObjectProperty:(NSString *)name associationPolicy:(objc_AssociationPolicy)policy; 27 | 28 | /** 29 | * 为类添加基础类型的属性,如:int,float,CGPoint,CGRect等 30 | * @param name 属性的name 31 | * @param type 属性的encodingType,如int类型的属性,type为@encode(int) 32 | */ 33 | + (void)addBasicProperty:(NSString *)name encodingType:(char *)type; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LcCategoryProperty/NSObject+LcProperty.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+LcProperty.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "NSObject+LcProperty.h" 10 | #import 11 | 12 | NSString *LcAddPropertyException = @"LcAddPropertyException"; 13 | 14 | @implementation NSObject (LcProperty) 15 | 16 | 17 | static inline NSString *__lc_setter_selector_name_of_property(NSString *property) 18 | { 19 | NSString *headCharacter = [[property substringToIndex:1] uppercaseString]; 20 | NSString *OtherString = [property substringFromIndex:1]; 21 | return [NSString stringWithFormat:@"set%@%@:",headCharacter,OtherString]; 22 | } 23 | 24 | + (void)addObjectProperty:(NSString *)name 25 | { 26 | [self addObjectProperty:name associationPolicy:OBJC_ASSOCIATION_RETAIN_NONATOMIC]; 27 | } 28 | 29 | 30 | + (void)addObjectProperty:(NSString *)name associationPolicy:(objc_AssociationPolicy)policy 31 | { 32 | if (!name.length) { 33 | [[NSException exceptionWithName:LcAddPropertyException 34 | reason:@"property must not be empty in +addObjectProperty:associationPolicy:" 35 | userInfo:@{@"name":name,@"policy":@(policy)}] 36 | raise]; 37 | } 38 | 39 | //1. 通过class的指针和property的name,创建一个唯一的key 40 | NSString *key = [NSString stringWithFormat:@"%p_%@",self,name]; 41 | 42 | //2. 用block实现setter方法 43 | id setblock = ^(id self,id value){ 44 | objc_setAssociatedObject(self, (__bridge void *)key, value, policy); 45 | }; 46 | 47 | //3. 将block的实现转化为IMP 48 | IMP imp = imp_implementationWithBlock(setblock); 49 | 50 | //4. 用name拼接出setter方法 51 | NSString *selString = __lc_setter_selector_name_of_property(name); 52 | 53 | //5. 将setter方法加入到class中 54 | BOOL result = class_addMethod([self class], NSSelectorFromString(selString), imp, "v@:@"); 55 | assert(result); 56 | 57 | //6. getter 58 | id getBlock = ^id(id self){ 59 | return objc_getAssociatedObject(self, (__bridge void*)key); 60 | }; 61 | IMP getImp = imp_implementationWithBlock(getBlock); 62 | result = class_addMethod([self class], NSSelectorFromString(name), getImp, "@@:"); 63 | assert(result); 64 | } 65 | 66 | 67 | + (void)addBasicProperty:(NSString *)name encodingType:(char *)type 68 | { 69 | if (!name.length) { 70 | [[NSException exceptionWithName:LcAddPropertyException 71 | reason:@"property must not be empty in +addBasicProperty:encodingType:" 72 | userInfo:@{@"name":name,@"type":@(type)}] 73 | raise]; 74 | } 75 | 76 | if (strcmp(type, @encode(id)) == 0) { 77 | [self addObjectProperty:name]; 78 | } 79 | NSString *key = [NSString stringWithFormat:@"%p_%@",self,name]; 80 | id setblock; 81 | id getBlock; 82 | #define blockWithCaseType(C_TYPE) \ 83 | if (strcmp(type, @encode(C_TYPE)) == 0) { \ 84 | setblock = ^(id self,C_TYPE var){ \ 85 | NSValue *value = [NSValue value:&var withObjCType:type];\ 86 | objc_setAssociatedObject(self, (__bridge void *)key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); \ 87 | }; \ 88 | getBlock = ^C_TYPE (id self){ \ 89 | NSValue *value = objc_getAssociatedObject(self, (__bridge void*)key); \ 90 | C_TYPE var; \ 91 | [value getValue:&var]; \ 92 | return var; \ 93 | }; \ 94 | } 95 | blockWithCaseType(char); 96 | blockWithCaseType(unsigned char); 97 | blockWithCaseType(short); 98 | blockWithCaseType(int); 99 | blockWithCaseType(unsigned int); 100 | blockWithCaseType(long); 101 | blockWithCaseType(unsigned long); 102 | blockWithCaseType(long long); 103 | blockWithCaseType(float); 104 | blockWithCaseType(double); 105 | blockWithCaseType(BOOL); 106 | 107 | blockWithCaseType(CGPoint); 108 | blockWithCaseType(CGSize); 109 | blockWithCaseType(CGVector); 110 | blockWithCaseType(CGRect); 111 | blockWithCaseType(NSRange); 112 | blockWithCaseType(CFRange); 113 | blockWithCaseType(CGAffineTransform); 114 | blockWithCaseType(CATransform3D); 115 | blockWithCaseType(UIOffset); 116 | blockWithCaseType(UIEdgeInsets); 117 | #undef blockWithCaseType 118 | 119 | if (!setblock || !getBlock) { 120 | [[NSException exceptionWithName:LcAddPropertyException 121 | reason:@"type is an unknown type in +addBasicProperty:encodingType:" 122 | userInfo:@{@"name":name,@"type":@(type)}] 123 | raise]; 124 | } 125 | 126 | IMP setImp = imp_implementationWithBlock(setblock); 127 | NSString *selString = __lc_setter_selector_name_of_property(name); 128 | NSString *setType = [NSString stringWithFormat:@"v@:%@",@(type)]; 129 | BOOL result = class_addMethod([self class], NSSelectorFromString(selString), setImp, [setType UTF8String]); 130 | assert(result); 131 | 132 | IMP getImp = imp_implementationWithBlock(getBlock); 133 | NSString *getType = [NSString stringWithFormat:@"%@@:",@(type)]; 134 | result = class_addMethod([self class], NSSelectorFromString(name), getImp, [getType UTF8String]); 135 | assert(result); 136 | } 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 75879F211C00228E002A047C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 75879F201C00228E002A047C /* main.m */; }; 11 | 75879F241C00228E002A047C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 75879F231C00228E002A047C /* AppDelegate.m */; }; 12 | 75879F271C00228E002A047C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 75879F261C00228E002A047C /* ViewController.m */; }; 13 | 75879F2A1C00228E002A047C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75879F281C00228E002A047C /* Main.storyboard */; }; 14 | 75879F2C1C00228E002A047C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75879F2B1C00228E002A047C /* Assets.xcassets */; }; 15 | 75879F2F1C00228E002A047C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75879F2D1C00228E002A047C /* LaunchScreen.storyboard */; }; 16 | 75879F3C1C002437002A047C /* Model.m in Sources */ = {isa = PBXBuildFile; fileRef = 75879F3B1C002437002A047C /* Model.m */; }; 17 | 75879F421C0032C6002A047C /* Model+Property.m in Sources */ = {isa = PBXBuildFile; fileRef = 75879F411C0032C6002A047C /* Model+Property.m */; }; 18 | 759361111C006341000813DC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 759361101C006341000813DC /* Foundation.framework */; }; 19 | 759361141C00635B000813DC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 759361131C00635B000813DC /* UIKit.framework */; }; 20 | 759361171C0063AB000813DC /* NSObject+LcProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 759361161C0063AB000813DC /* NSObject+LcProperty.m */; }; 21 | 75FC93111C01681C00194561 /* NSObject+LcInvokeAllMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 75FC93101C01681C00194561 /* NSObject+LcInvokeAllMethod.m */; }; 22 | 75FC93141C016EEA00194561 /* Model+second.m in Sources */ = {isa = PBXBuildFile; fileRef = 75FC93131C016EEA00194561 /* Model+second.m */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 75879F1C1C00228E002A047C /* LcCategoryPropertySample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LcCategoryPropertySample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 75879F201C00228E002A047C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 28 | 75879F221C00228E002A047C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 29 | 75879F231C00228E002A047C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 30 | 75879F251C00228E002A047C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 31 | 75879F261C00228E002A047C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 32 | 75879F291C00228E002A047C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 33 | 75879F2B1C00228E002A047C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 34 | 75879F2E1C00228E002A047C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 35 | 75879F301C00228E002A047C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 75879F3A1C002437002A047C /* Model.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Model.h; sourceTree = ""; }; 37 | 75879F3B1C002437002A047C /* Model.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Model.m; sourceTree = ""; }; 38 | 75879F401C0032C6002A047C /* Model+Property.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Model+Property.h"; sourceTree = ""; }; 39 | 75879F411C0032C6002A047C /* Model+Property.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Model+Property.m"; sourceTree = ""; }; 40 | 759361101C006341000813DC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | 759361131C00635B000813DC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 42 | 759361151C0063AB000813DC /* NSObject+LcProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+LcProperty.h"; sourceTree = ""; }; 43 | 759361161C0063AB000813DC /* NSObject+LcProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+LcProperty.m"; sourceTree = ""; }; 44 | 75FC930F1C01681C00194561 /* NSObject+LcInvokeAllMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+LcInvokeAllMethod.h"; sourceTree = ""; }; 45 | 75FC93101C01681C00194561 /* NSObject+LcInvokeAllMethod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+LcInvokeAllMethod.m"; sourceTree = ""; }; 46 | 75FC93121C016EEA00194561 /* Model+second.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Model+second.h"; sourceTree = ""; }; 47 | 75FC93131C016EEA00194561 /* Model+second.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Model+second.m"; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | 75879F191C00228E002A047C /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | 759361141C00635B000813DC /* UIKit.framework in Frameworks */, 56 | 759361111C006341000813DC /* Foundation.framework in Frameworks */, 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | 75879F131C00228E002A047C = { 64 | isa = PBXGroup; 65 | children = ( 66 | 75879F361C002325002A047C /* LcCategoryProperty */, 67 | 75879F1E1C00228E002A047C /* LcCategoryPropertySample */, 68 | 75879F1D1C00228E002A047C /* Products */, 69 | 759361121C00634A000813DC /* Frameworks */, 70 | ); 71 | sourceTree = ""; 72 | }; 73 | 75879F1D1C00228E002A047C /* Products */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 75879F1C1C00228E002A047C /* LcCategoryPropertySample.app */, 77 | ); 78 | name = Products; 79 | sourceTree = ""; 80 | }; 81 | 75879F1E1C00228E002A047C /* LcCategoryPropertySample */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 75879F3A1C002437002A047C /* Model.h */, 85 | 75879F3B1C002437002A047C /* Model.m */, 86 | 75879F401C0032C6002A047C /* Model+Property.h */, 87 | 75879F411C0032C6002A047C /* Model+Property.m */, 88 | 75FC93121C016EEA00194561 /* Model+second.h */, 89 | 75FC93131C016EEA00194561 /* Model+second.m */, 90 | 75879F221C00228E002A047C /* AppDelegate.h */, 91 | 75879F231C00228E002A047C /* AppDelegate.m */, 92 | 75879F251C00228E002A047C /* ViewController.h */, 93 | 75879F261C00228E002A047C /* ViewController.m */, 94 | 75879F281C00228E002A047C /* Main.storyboard */, 95 | 75879F2B1C00228E002A047C /* Assets.xcassets */, 96 | 75879F2D1C00228E002A047C /* LaunchScreen.storyboard */, 97 | 75879F301C00228E002A047C /* Info.plist */, 98 | 75879F1F1C00228E002A047C /* Supporting Files */, 99 | ); 100 | path = LcCategoryPropertySample; 101 | sourceTree = ""; 102 | }; 103 | 75879F1F1C00228E002A047C /* Supporting Files */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 75879F201C00228E002A047C /* main.m */, 107 | ); 108 | name = "Supporting Files"; 109 | sourceTree = ""; 110 | }; 111 | 75879F361C002325002A047C /* LcCategoryProperty */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 759361151C0063AB000813DC /* NSObject+LcProperty.h */, 115 | 759361161C0063AB000813DC /* NSObject+LcProperty.m */, 116 | 75FC930F1C01681C00194561 /* NSObject+LcInvokeAllMethod.h */, 117 | 75FC93101C01681C00194561 /* NSObject+LcInvokeAllMethod.m */, 118 | ); 119 | name = LcCategoryProperty; 120 | path = ../LcCategoryProperty; 121 | sourceTree = ""; 122 | }; 123 | 759361121C00634A000813DC /* Frameworks */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 759361131C00635B000813DC /* UIKit.framework */, 127 | 759361101C006341000813DC /* Foundation.framework */, 128 | ); 129 | name = Frameworks; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | 75879F1B1C00228E002A047C /* LcCategoryPropertySample */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 75879F331C00228E002A047C /* Build configuration list for PBXNativeTarget "LcCategoryPropertySample" */; 138 | buildPhases = ( 139 | 75879F181C00228E002A047C /* Sources */, 140 | 75879F191C00228E002A047C /* Frameworks */, 141 | 75879F1A1C00228E002A047C /* Resources */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = LcCategoryPropertySample; 148 | productName = LcCategoryPropertySample; 149 | productReference = 75879F1C1C00228E002A047C /* LcCategoryPropertySample.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | 75879F141C00228E002A047C /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | LastUpgradeCheck = 0710; 159 | ORGANIZATIONNAME = jiangliancheng; 160 | TargetAttributes = { 161 | 75879F1B1C00228E002A047C = { 162 | CreatedOnToolsVersion = 7.1; 163 | }; 164 | }; 165 | }; 166 | buildConfigurationList = 75879F171C00228E002A047C /* Build configuration list for PBXProject "LcCategoryPropertySample" */; 167 | compatibilityVersion = "Xcode 3.2"; 168 | developmentRegion = English; 169 | hasScannedForEncodings = 0; 170 | knownRegions = ( 171 | en, 172 | Base, 173 | ); 174 | mainGroup = 75879F131C00228E002A047C; 175 | productRefGroup = 75879F1D1C00228E002A047C /* Products */; 176 | projectDirPath = ""; 177 | projectRoot = ""; 178 | targets = ( 179 | 75879F1B1C00228E002A047C /* LcCategoryPropertySample */, 180 | ); 181 | }; 182 | /* End PBXProject section */ 183 | 184 | /* Begin PBXResourcesBuildPhase section */ 185 | 75879F1A1C00228E002A047C /* Resources */ = { 186 | isa = PBXResourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | 75879F2F1C00228E002A047C /* LaunchScreen.storyboard in Resources */, 190 | 75879F2C1C00228E002A047C /* Assets.xcassets in Resources */, 191 | 75879F2A1C00228E002A047C /* Main.storyboard in Resources */, 192 | ); 193 | runOnlyForDeploymentPostprocessing = 0; 194 | }; 195 | /* End PBXResourcesBuildPhase section */ 196 | 197 | /* Begin PBXSourcesBuildPhase section */ 198 | 75879F181C00228E002A047C /* Sources */ = { 199 | isa = PBXSourcesBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | 75879F421C0032C6002A047C /* Model+Property.m in Sources */, 203 | 75FC93141C016EEA00194561 /* Model+second.m in Sources */, 204 | 75879F271C00228E002A047C /* ViewController.m in Sources */, 205 | 75879F241C00228E002A047C /* AppDelegate.m in Sources */, 206 | 759361171C0063AB000813DC /* NSObject+LcProperty.m in Sources */, 207 | 75879F211C00228E002A047C /* main.m in Sources */, 208 | 75FC93111C01681C00194561 /* NSObject+LcInvokeAllMethod.m in Sources */, 209 | 75879F3C1C002437002A047C /* Model.m in Sources */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | /* End PBXSourcesBuildPhase section */ 214 | 215 | /* Begin PBXVariantGroup section */ 216 | 75879F281C00228E002A047C /* Main.storyboard */ = { 217 | isa = PBXVariantGroup; 218 | children = ( 219 | 75879F291C00228E002A047C /* Base */, 220 | ); 221 | name = Main.storyboard; 222 | sourceTree = ""; 223 | }; 224 | 75879F2D1C00228E002A047C /* LaunchScreen.storyboard */ = { 225 | isa = PBXVariantGroup; 226 | children = ( 227 | 75879F2E1C00228E002A047C /* Base */, 228 | ); 229 | name = LaunchScreen.storyboard; 230 | sourceTree = ""; 231 | }; 232 | /* End PBXVariantGroup section */ 233 | 234 | /* Begin XCBuildConfiguration section */ 235 | 75879F311C00228E002A047C /* Debug */ = { 236 | isa = XCBuildConfiguration; 237 | buildSettings = { 238 | ALWAYS_SEARCH_USER_PATHS = NO; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BOOL_CONVERSION = YES; 244 | CLANG_WARN_CONSTANT_CONVERSION = YES; 245 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 246 | CLANG_WARN_EMPTY_BODY = YES; 247 | CLANG_WARN_ENUM_CONVERSION = YES; 248 | CLANG_WARN_INT_CONVERSION = YES; 249 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 250 | CLANG_WARN_UNREACHABLE_CODE = YES; 251 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 252 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 253 | COPY_PHASE_STRIP = NO; 254 | DEBUG_INFORMATION_FORMAT = dwarf; 255 | ENABLE_STRICT_OBJC_MSGSEND = YES; 256 | ENABLE_TESTABILITY = YES; 257 | GCC_C_LANGUAGE_STANDARD = gnu99; 258 | GCC_DYNAMIC_NO_PIC = NO; 259 | GCC_NO_COMMON_BLOCKS = YES; 260 | GCC_OPTIMIZATION_LEVEL = 0; 261 | GCC_PREPROCESSOR_DEFINITIONS = ( 262 | "DEBUG=1", 263 | "$(inherited)", 264 | ); 265 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 266 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 267 | GCC_WARN_UNDECLARED_SELECTOR = YES; 268 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 269 | GCC_WARN_UNUSED_FUNCTION = YES; 270 | GCC_WARN_UNUSED_VARIABLE = YES; 271 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 272 | MTL_ENABLE_DEBUG_INFO = YES; 273 | ONLY_ACTIVE_ARCH = YES; 274 | SDKROOT = iphoneos; 275 | }; 276 | name = Debug; 277 | }; 278 | 75879F321C00228E002A047C /* Release */ = { 279 | isa = XCBuildConfiguration; 280 | buildSettings = { 281 | ALWAYS_SEARCH_USER_PATHS = NO; 282 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 283 | CLANG_CXX_LIBRARY = "libc++"; 284 | CLANG_ENABLE_MODULES = YES; 285 | CLANG_ENABLE_OBJC_ARC = YES; 286 | CLANG_WARN_BOOL_CONVERSION = YES; 287 | CLANG_WARN_CONSTANT_CONVERSION = YES; 288 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 289 | CLANG_WARN_EMPTY_BODY = YES; 290 | CLANG_WARN_ENUM_CONVERSION = YES; 291 | CLANG_WARN_INT_CONVERSION = YES; 292 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 293 | CLANG_WARN_UNREACHABLE_CODE = YES; 294 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 295 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 296 | COPY_PHASE_STRIP = NO; 297 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 298 | ENABLE_NS_ASSERTIONS = NO; 299 | ENABLE_STRICT_OBJC_MSGSEND = YES; 300 | GCC_C_LANGUAGE_STANDARD = gnu99; 301 | GCC_NO_COMMON_BLOCKS = YES; 302 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 303 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 304 | GCC_WARN_UNDECLARED_SELECTOR = YES; 305 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 306 | GCC_WARN_UNUSED_FUNCTION = YES; 307 | GCC_WARN_UNUSED_VARIABLE = YES; 308 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 309 | MTL_ENABLE_DEBUG_INFO = NO; 310 | SDKROOT = iphoneos; 311 | VALIDATE_PRODUCT = YES; 312 | }; 313 | name = Release; 314 | }; 315 | 75879F341C00228E002A047C /* Debug */ = { 316 | isa = XCBuildConfiguration; 317 | buildSettings = { 318 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 319 | INFOPLIST_FILE = LcCategoryPropertySample/Info.plist; 320 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 321 | PRODUCT_BUNDLE_IDENTIFIER = com.liancheng.LcCategoryPropertySample; 322 | PRODUCT_NAME = "$(TARGET_NAME)"; 323 | }; 324 | name = Debug; 325 | }; 326 | 75879F351C00228E002A047C /* Release */ = { 327 | isa = XCBuildConfiguration; 328 | buildSettings = { 329 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 330 | INFOPLIST_FILE = LcCategoryPropertySample/Info.plist; 331 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 332 | PRODUCT_BUNDLE_IDENTIFIER = com.liancheng.LcCategoryPropertySample; 333 | PRODUCT_NAME = "$(TARGET_NAME)"; 334 | }; 335 | name = Release; 336 | }; 337 | /* End XCBuildConfiguration section */ 338 | 339 | /* Begin XCConfigurationList section */ 340 | 75879F171C00228E002A047C /* Build configuration list for PBXProject "LcCategoryPropertySample" */ = { 341 | isa = XCConfigurationList; 342 | buildConfigurations = ( 343 | 75879F311C00228E002A047C /* Debug */, 344 | 75879F321C00228E002A047C /* Release */, 345 | ); 346 | defaultConfigurationIsVisible = 0; 347 | defaultConfigurationName = Release; 348 | }; 349 | 75879F331C00228E002A047C /* Build configuration list for PBXNativeTarget "LcCategoryPropertySample" */ = { 350 | isa = XCConfigurationList; 351 | buildConfigurations = ( 352 | 75879F341C00228E002A047C /* Debug */, 353 | 75879F351C00228E002A047C /* Release */, 354 | ); 355 | defaultConfigurationIsVisible = 0; 356 | defaultConfigurationName = Release; 357 | }; 358 | /* End XCConfigurationList section */ 359 | }; 360 | rootObject = 75879F141C00228E002A047C /* Project object */; 361 | } 362 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Model+Property.h: -------------------------------------------------------------------------------- 1 | // 2 | // Model+Property.h 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | #import 11 | 12 | @interface Model (Property) 13 | @property (nonatomic, assign)CGPoint point; 14 | @property (nonatomic, assign)CGRect myRect; 15 | 16 | @property (nonatomic, assign)float f; 17 | @property (nonatomic, assign)int a; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Model+Property.m: -------------------------------------------------------------------------------- 1 | // 2 | // Model+Property.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "Model+Property.h" 10 | #import "NSObject+LcProperty.h" 11 | 12 | @implementation Model (Property) 13 | 14 | + (void)categoryInitialize 15 | { 16 | [self addBasicProperty:@"point" encodingType:@encode(CGPoint)]; 17 | [self addBasicProperty:@"myRect" encodingType:@encode(CGRect)]; 18 | [self addBasicProperty:@"f" encodingType:@encode(float)]; 19 | [self addBasicProperty:@"a" encodingType:@encode(int)]; 20 | } 21 | 22 | @end 23 | 24 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Model+second.h: -------------------------------------------------------------------------------- 1 | // 2 | // Model+second.h 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/22. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | 11 | @interface Model (second) 12 | @property (nonatomic, strong)NSString *name; 13 | @property (nonatomic, strong)NSURL *URL; 14 | @property (nonatomic, strong)NSDate *date; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Model+second.m: -------------------------------------------------------------------------------- 1 | // 2 | // Model+second.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/22. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "Model+second.h" 10 | #import "NSObject+LcProperty.h" 11 | 12 | @implementation Model (second) 13 | @dynamic name; 14 | @dynamic URL; 15 | @dynamic date; 16 | 17 | + (void)categoryInitialize 18 | { 19 | [self addObjectProperty:@"URL"]; 20 | [self addObjectProperty:@"date"]; 21 | [self addObjectProperty:@"name" associationPolicy:OBJC_ASSOCIATION_COPY_NONATOMIC]; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Model.h: -------------------------------------------------------------------------------- 1 | // 2 | // Model.h 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Model : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/Model.m: -------------------------------------------------------------------------------- 1 | // 2 | // Model.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | #import "NSObject+LcInvokeAllMethod.h" 11 | 12 | @implementation Model 13 | 14 | + (void)initialize 15 | { 16 | [self invokeAllClassMethodWithSelector:@selector(categoryInitialize)]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "Model+Property.h" 11 | #import "Model+second.h" 12 | 13 | @interface ViewController () 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view, typically from a nib. 22 | Model *model = [[Model alloc] init]; 23 | model.name = @"name"; 24 | model.f = 4.2; 25 | model.a = 89.2; 26 | model.point = CGPointZero; 27 | model.myRect = CGRectMake(0, 78, 67, 67); 28 | NSLog(@"name:%@",model.name); 29 | } 30 | 31 | - (void)didReceiveMemoryWarning { 32 | [super didReceiveMemoryWarning]; 33 | // Dispose of any resources that can be recreated. 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /LcCategoryPropertySample/LcCategoryPropertySample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LcCategoryPropertySample 4 | // 5 | // Created by jiangliancheng on 15/11/21. 6 | // Copyright © 2015年 jiangliancheng. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #LcCategoryProperty 2 | --- 3 | handy add property in category use runtime 4 | 只需要调用一个方法,就可以在Category中使用Property 5 | 6 | #Installation 7 | Drag LcCategoryProperty folder to your project 8 | 安装方法:将LcCategoryProperty文件夹拖到你的工程中 9 | 10 | #Usage 11 | 12 | @interface Model (Property) 13 | @property (nonatomic, strong)NSString *name; 14 | @property (nonatomic, strong)NSURL *URL; 15 | @property (nonatomic, strong)NSDate *date; 16 | 17 | @property (nonatomic, assign)CGPoint point; 18 | @property (nonatomic, assign)CGRect myRect; 19 | 20 | @property (nonatomic, assign)float f; 21 | @property (nonatomic, assign)int a; 22 | 23 | @end 24 | 25 | @implementation Model (Property) 26 | 27 | + (void)load 28 | { 29 | [self addObjectProperty:@"URL"]; 30 | [self addObjectProperty:@"date"]; 31 | [self addObjectProperty:@"name" associationPolicy:OBJC_ASSOCIATION_COPY_NONATOMIC]; 32 | [self addBasicProperty:@"point" encodingType:@encode(CGPoint)]; 33 | [self addBasicProperty:@"myRect" encodingType:@encode(CGRect)]; 34 | [self addBasicProperty:@"f" encodingType:@encode(float)]; 35 | [self addBasicProperty:@"a" encodingType:@encode(int)]; 36 | } 37 | 38 | @end 39 | 40 | --------------------------------------------------------------------------------