├── .gitignore ├── Assets ├── RuntimeSummary.png └── Screenshot.png ├── AssociatedObject ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── NSObject+Property.h ├── NSObject+Property.m ├── ViewController.h ├── ViewController.m └── main.m ├── ForwardMessage ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Cat.h ├── Cat.m ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── LICENSE ├── MakeModel ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── GithubUser.h ├── GithubUser.m ├── Info.plist ├── NSObject+Model.h ├── NSObject+Model.m ├── ViewController.h ├── ViewController.m └── main.m ├── Messaging ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Cat.h ├── Cat.m ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── MethodSwizzling ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── UIImage+Success.h ├── UIImage+Success.m ├── ViewController.h ├── ViewController.m └── main.m ├── ObjectArchive ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Cat.h ├── Cat.m ├── Info.plist ├── NSObject+Archive.h ├── NSObject+Archive.m ├── ViewController.h ├── ViewController.m └── main.m ├── README.md ├── ResolveInstanceMethod ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Cat.h ├── Cat.m ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m └── RuntimeSummary.xcodeproj ├── project.pbxproj └── project.xcworkspace └── contents.xcworkspacedata /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/objective-c 3 | 4 | ### Objective-C ### 5 | # Xcode 6 | # 7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 8 | 9 | ## Build generated 10 | build/ 11 | DerivedData/ 12 | 13 | ## Various settings 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata/ 23 | 24 | ## Other 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | # fastlane 48 | # 49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 50 | # screenshots whenever they are needed. 51 | # For more information about the recommended setup visit: 52 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 53 | 54 | fastlane/report.xml 55 | fastlane/screenshots 56 | 57 | ### Objective-C Patch ### 58 | *.xcscmblueprint 59 | 60 | -------------------------------------------------------------------------------- /Assets/RuntimeSummary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tuccuay/RuntimeSummary/501c3cc90e2d77e766966646e18a7b4144067fac/Assets/RuntimeSummary.png -------------------------------------------------------------------------------- /Assets/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tuccuay/RuntimeSummary/501c3cc90e2d77e766966646e18a7b4144067fac/Assets/Screenshot.png -------------------------------------------------------------------------------- /AssociatedObject/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AssociatedObject 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /AssociatedObject/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AssociatedObject 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /AssociatedObject/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /AssociatedObject/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 | -------------------------------------------------------------------------------- /AssociatedObject/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 | -------------------------------------------------------------------------------- /AssociatedObject/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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /AssociatedObject/NSObject+Property.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Property.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (Property) 12 | 13 | // @property 在分类中只会生成 getter/setter 方法 14 | // 不会生成成员属性 15 | @property NSString *name; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /AssociatedObject/NSObject+Property.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Property.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "NSObject+Property.h" 10 | 11 | #import 12 | 13 | @implementation NSObject (Property) 14 | 15 | // 这种方法生成的变量不受对象控制 16 | // NSString *_name; 17 | 18 | - (void)setName:(NSString *)name { 19 | // 把属性关联给对象 20 | objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 21 | } 22 | 23 | - (NSString *)name { 24 | // 取出属性 25 | return objc_getAssociatedObject(self, "name"); 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /AssociatedObject/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // AssociatedObject 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /AssociatedObject/ViewController.m: -------------------------------------------------------------------------------- 1 | // RuntimeSummary - 一个集合了常用 Objective-C Runtime 用法的 Playground 2 | // https://github.com/Tuccuay/RuntimeSummary 3 | 4 | // AssociatedObject / 动态关联属性 5 | 6 | #import "ViewController.h" 7 | 8 | #import "NSObject+Property.h" 9 | 10 | @interface ViewController () 11 | 12 | @end 13 | 14 | @implementation ViewController 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | 19 | NSObject *anObject = [[NSObject alloc] init]; 20 | 21 | anObject.name = @"Alton"; 22 | 23 | // NSObject 并没有 name 这个属性,通过 Runtime 成功的添加了这个属性 24 | NSLog(@"%@", anObject.name); 25 | 26 | // 输出: 27 | // 2016-04-21 22:15:24.502 AssociatedObject[21577:1914668] Alton 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /AssociatedObject/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AssociatedObject 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ForwardMessage/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ForwardMessage 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ForwardMessage/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ForwardMessage 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ForwardMessage/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /ForwardMessage/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 | -------------------------------------------------------------------------------- /ForwardMessage/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /ForwardMessage/Cat.h: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Cat : NSObject 12 | 13 | + (void)stoke; 14 | 15 | - (void)stoke; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ForwardMessage/Cat.m: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "Cat.h" 10 | 11 | @implementation Cat 12 | 13 | #pragma mark - 实例方法 14 | 15 | // 第一步 16 | // 在没有找到方法时,会先调用此方法,可用于动态添加方法 17 | // 返回 YES 表示相应 selector 的实现已经被找到并添加到了类中,否则返回 NO 18 | 19 | + (BOOL)resolveInstanceMethod:(SEL)sel { 20 | return YES; 21 | } 22 | 23 | // 第二步 24 | // 如果第一步的返回 NO 或者直接返回了 YES 而没有添加方法,该方法被调用 25 | // 在这个方法中,我们可以指定一个可以返回一个可以响应该方法的对象 26 | // 如果返回 self 就会死循环 27 | 28 | - (id)forwardingTargetForSelector:(SEL)aSelector { 29 | return nil; 30 | } 31 | 32 | // 第三步 33 | // 如果 `forwardingTargetForSelector:` 返回了 nil,则该方法会被调用,系统会询问我们要一个合法的『类型编码(Type Encoding)』 34 | // https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html 35 | // 若返回 nil,则不会进入下一步,而是无法处理消息 36 | 37 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 38 | return [NSMethodSignature signatureWithObjCTypes:"v@:"]; 39 | } 40 | 41 | // 当实现了此方法后,-doesNotRecognizeSelector: 将不会被调用 42 | // 如果要测试找不到方法,可以注释掉这一个方法 43 | // 在这里进行消息转发 44 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 45 | // 我们还可以改变方法选择器 46 | [anInvocation setSelector:@selector(touch)]; 47 | // 改变方法选择器后,还需要指定是哪个对象的方法 48 | [anInvocation invokeWithTarget:self]; 49 | } 50 | 51 | - (void)touch { 52 | NSLog(@"Cat 没有实现 -stoke 方法,并且成功的转成了 -touch 方法"); 53 | } 54 | 55 | - (void)doesNotRecognizeSelector:(SEL)aSelector { 56 | NSLog(@"无法处理消息:%@", NSStringFromSelector(aSelector)); 57 | } 58 | 59 | #pragma mark - 类方法 60 | 61 | // 类方法也会直接消息转发机制 62 | // 不过有些东西可能会比较有趣: 63 | // 下述方法中: 64 | // forwardingTargetForSelector 65 | // methodSignatureForSelector 66 | // forwardInvocation 67 | // doesNotRecognizeSelector 68 | // 我们将前面的修饰符由 "-" 替换为了 "+", 69 | // 但当我们在上述各个方法中的实现用调用 [super method] 时,method 的定义还是 NSObject 的实例方法 70 | // 这可能就和元类(MetaClass)相关了 71 | 72 | // 与 resolveInstanceMethod 相对应 73 | + (BOOL)resolveClassMethod:(SEL)sel { 74 | return NO; 75 | } 76 | 77 | + (id)forwardingTargetForSelector:(SEL)aSelector { 78 | return nil; 79 | } 80 | 81 | + (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 82 | return [NSMethodSignature signatureWithObjCTypes:"v@:"]; 83 | } 84 | 85 | + (void)forwardInvocation:(NSInvocation *)anInvocation { 86 | [anInvocation setSelector:@selector(touch)]; 87 | [anInvocation invokeWithTarget:self]; 88 | } 89 | 90 | + (void)touch { 91 | NSLog(@"Cat 没有实现 +stoke 方法,并且成功的转成了 +touch 方法"); 92 | } 93 | 94 | + (void)doesNotRecognizeSelector:(SEL)aSelector { 95 | NSLog(@"无法处理消息:%@", NSStringFromSelector(aSelector)); 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /ForwardMessage/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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ForwardMessage/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ForwardMessage 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ForwardMessage/ViewController.m: -------------------------------------------------------------------------------- 1 | // RuntimeSummary - 一个集合了常用 Objective-C Runtime 用法的 Playground 2 | // https://github.com/Tuccuay/RuntimeSummary 3 | 4 | // ForwardMessage / 消息转发 5 | 6 | #import "ViewController.h" 7 | #import "Cat.h" 8 | 9 | @interface ViewController () 10 | 11 | @end 12 | 13 | @implementation ViewController 14 | 15 | - (IBAction)instanceMethodCalling { 16 | [[Cat new] stoke]; 17 | } 18 | 19 | - (IBAction)classMethodCalling { 20 | [Cat stoke]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /ForwardMessage/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ForwardMessage 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Tuccuay 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MakeModel/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MakeModel 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /MakeModel/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MakeModel 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /MakeModel/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /MakeModel/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 | -------------------------------------------------------------------------------- /MakeModel/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 | 27 | -------------------------------------------------------------------------------- /MakeModel/GithubUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // GithubUser.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GithubUser : NSObject 12 | 13 | @property (nonatomic, strong) NSString *location; 14 | 15 | @property (nonatomic, assign) NSNumber *public_gists; 16 | 17 | @property (nonatomic, strong) NSString *url; 18 | 19 | @property (nonatomic, strong) NSString *following_url; 20 | 21 | @property (nonatomic, strong) NSString *events_url; 22 | 23 | @property (nonatomic, strong) NSString *received_events_url; 24 | 25 | @property (nonatomic, strong) NSString *company; 26 | 27 | @property (nonatomic, strong) NSString *updated_at; 28 | 29 | @property (nonatomic, strong) NSString *avatar_url; 30 | 31 | @property (nonatomic, strong) NSString *name; 32 | 33 | @property (nonatomic, strong) NSString *type; 34 | 35 | @property (nonatomic, strong) NSString *subscriptions_url; 36 | 37 | @property (nonatomic, strong) NSString *gists_url; 38 | 39 | @property (nonatomic, assign) NSNumber *ID; 40 | 41 | @property (nonatomic, strong) NSString *starred_url; 42 | 43 | @property (nonatomic, strong) NSString *organizations_url; 44 | 45 | @property (nonatomic, strong) NSString *repos_url; 46 | 47 | @property (nonatomic, assign) BOOL site_admin; 48 | 49 | @property (nonatomic, strong) NSString *email; 50 | 51 | @property (nonatomic, strong) NSString *login; 52 | 53 | @property (nonatomic, strong) NSString *blog; 54 | 55 | @property (nonatomic, assign) NSNumber *public_repos; 56 | 57 | @property (nonatomic, assign) NSNumber *followers; 58 | 59 | @property (nonatomic, assign) NSNumber *following; 60 | 61 | @property (nonatomic, strong) NSString *created_at; 62 | 63 | @property (nonatomic, strong) NSString *gravatar_id; 64 | 65 | @property (nonatomic, strong) NSString *followers_url; 66 | 67 | @property (nonatomic, strong) NSString *html_url; 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /MakeModel/GithubUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // GithubUser.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "GithubUser.h" 10 | 11 | @implementation GithubUser 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MakeModel/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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /MakeModel/NSObject+Model.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Model.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (Model) 12 | 13 | + (instancetype)modelWithDict:(NSDictionary *)dict; 14 | + (instancetype)modelWithDict:(NSDictionary *)dict updateDict:(NSDictionary *)updateDict; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MakeModel/NSObject+Model.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Model.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "NSObject+Model.h" 10 | 11 | #import 12 | 13 | @implementation NSObject (Model) 14 | 15 | + (instancetype)modelWithDict:(NSDictionary *)dict updateDict:(NSDictionary *)updateDict { 16 | id model = [[self alloc] init]; 17 | // 遍历模型中属性 18 | unsigned int count = 0; 19 | Ivar *ivars = class_copyIvarList(self, &count); 20 | for (int i = 0 ; i < count; i++) { 21 | Ivar ivar = ivars[i]; 22 | // 属性名称 23 | NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)]; 24 | ivarName = [ivarName substringFromIndex:1]; 25 | id value = dict[ivarName]; 26 | // 模型中属性名对应字典中的key 27 | if (value == nil) { 28 | if (updateDict) { 29 | NSString *keyName = updateDict[ivarName]; 30 | value = dict[keyName]; 31 | } 32 | } 33 | [model setValue:value forKeyPath:ivarName]; 34 | } 35 | return model; 36 | } 37 | 38 | + (instancetype)modelWithDict:(NSDictionary *)dict { 39 | return [self modelWithDict:dict updateDict:nil]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /MakeModel/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // MakeModel 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /MakeModel/ViewController.m: -------------------------------------------------------------------------------- 1 | // RuntimeSummary - 一个集合了常用 Objective-C Runtime 用法的 Playground 2 | // https://github.com/Tuccuay/RuntimeSummary 3 | 4 | // MakeModel / 字典转模型 5 | 6 | #import "ViewController.h" 7 | 8 | #import "NSObject+Model.h" 9 | 10 | #import "GithubUser.h" 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view, typically from a nib. 21 | 22 | // 从网络请求数据 23 | NSString *githubAPI = @"https://api.github.com/users/Tuccuay"; 24 | NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:githubAPI]]; 25 | NSURLSession *session = [NSURLSession sharedSession]; 26 | NSURLSessionDataTask *task = [session dataTaskWithRequest:request 27 | completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 28 | NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; 29 | 30 | // 因为 Github 的 API 中有一个字段是 id 31 | // 而 id 在 Objective-C 中已经被占用 32 | // GithubUser *tuccuay = [GithubUser modelWithDict:dict]; 33 | 34 | // 所以把 id 替换成 ID 35 | GithubUser *tuccuay = [GithubUser modelWithDict:dict updateDict:@{@"ID":@"id"}]; 36 | 37 | // 给下面的 NSLog 打个断点 38 | // 从调试器里能看见上面的 tuccuay 模型已经转好了 39 | NSLog(@"mew~"); 40 | }]; 41 | [task resume]; 42 | 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /MakeModel/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MakeModel 4 | // 5 | // Created by 朔 洪 on 16/4/23. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /Messaging/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Messaging 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /Messaging/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Messaging 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /Messaging/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Messaging/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 | -------------------------------------------------------------------------------- /Messaging/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 | -------------------------------------------------------------------------------- /Messaging/Cat.h: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Cat : NSObject 12 | 13 | // - (void)eat; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Messaging/Cat.m: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "Cat.h" 10 | 11 | @implementation Cat 12 | 13 | - (void)eat { 14 | NSLog(@"burbur~"); 15 | } 16 | 17 | - (void)run:(NSUInteger)metre 18 | { 19 | NSLog(@"跑了 %ld 米", metre); 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Messaging/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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Messaging/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Messaging 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /Messaging/ViewController.m: -------------------------------------------------------------------------------- 1 | // RuntimeSummary - 一个集合了常用 Objective-C Runtime 用法的 Playground 2 | // https://github.com/Tuccuay/RuntimeSummary 3 | 4 | // Messaging / 消息机制介绍 5 | 6 | #import "ViewController.h" 7 | 8 | #import "Cat.h" 9 | 10 | #import 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | // 创建一个对象 22 | // Cat *harlan = [[Cat alloc] init]; 23 | 24 | // 使用 Runtime 创建一个对象 25 | // 根据类名获取到类 26 | Class catClass = objc_getClass("Cat"); 27 | 28 | // 同过类创建实例对象 29 | // 如果这里报错,请将 Build Setting -> Enable Strict Checking of objc_msgSend Calls 改为 NO 30 | Cat *harlan = objc_msgSend(catClass, @selector(alloc)); 31 | 32 | // 初始化对象 33 | // harlan = [harlan init]; 34 | 35 | // 通过 Runtime 初始化对象 36 | harlan = objc_msgSend(harlan, @selector(init)); 37 | 38 | // 调用对象方法 39 | // [harlan eat]; 40 | 41 | // 通过 Runtime 调用对象方法 42 | // 调用的这个方法没有声明只有实现所以这里会有警告 43 | // 但是发送消息的时候会从方法列表里寻找方法 44 | // 所以这个能够成功执行 45 | objc_msgSend(harlan, @selector(eat)); 46 | 47 | // 输出: 2016-04-21 21:10:20.733 Messaging[20696:1825249] burbur~ 48 | 49 | // 当然,objc_msgSend 可以传递参数 50 | Cat *alex = objc_msgSend(objc_msgSend(objc_getClass("Cat"), sel_registerName("alloc")), sel_registerName("init")); 51 | objc_msgSend(alex, @selector(run:), 10); 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Messaging/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Messaging 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /MethodSwizzling/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MethodSwizzling 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /MethodSwizzling/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MethodSwizzling 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /MethodSwizzling/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /MethodSwizzling/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 | -------------------------------------------------------------------------------- /MethodSwizzling/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 | -------------------------------------------------------------------------------- /MethodSwizzling/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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /MethodSwizzling/UIImage+Success.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Success.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (Success) 12 | 13 | + (UIImage *)tuc_imageNamed:(NSString *)name; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /MethodSwizzling/UIImage+Success.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Success.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "UIImage+Success.h" 10 | 11 | #import 12 | 13 | @implementation UIImage (Success) 14 | 15 | + (void)load { 16 | // 获取到两个方法 17 | Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:)); 18 | Method tuc_imageNamedMethod = class_getClassMethod(self, @selector(tuc_imageNamed:)); 19 | 20 | // 交换方法 21 | method_exchangeImplementations(imageNamedMethod, tuc_imageNamedMethod); 22 | } 23 | 24 | + (UIImage *)tuc_imageNamed:(NSString *)name { 25 | // 因为来到这里的时候方法实际上已经被交换过了 26 | // 这里要调用 imageNamed: 就需要调换被交换过的 tuc_imageNamed 27 | UIImage *image = [UIImage tuc_imageNamed:name]; 28 | 29 | // 判断是否存在图片 30 | if (image) { 31 | NSLog(@"加载成功"); 32 | } else { 33 | NSLog(@"加载失败"); 34 | } 35 | 36 | return image; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /MethodSwizzling/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // MethodSwizzling 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /MethodSwizzling/ViewController.m: -------------------------------------------------------------------------------- 1 | // RuntimeSummary - 一个集合了常用 Objective-C Runtime 用法的 Playground 2 | // https://github.com/Tuccuay/RuntimeSummary 3 | 4 | // MethodSwizzling / 方法交换 5 | 6 | #import "ViewController.h" 7 | 8 | #import "UIImage+Success.h" 9 | 10 | @interface ViewController () 11 | 12 | @end 13 | 14 | @implementation ViewController 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | 19 | // 这里调用的是 imageNamed 20 | // 但实际上方法已经在 UIImage+Success 分类中被交换了 21 | // 所以这个能够提示图片是否加载成功 22 | UIImage *image = [UIImage imageNamed:@"picture"]; 23 | 24 | // 因为名为 picture 的图片不存在,所以输出是 25 | // 2016-04-21 21:40:31.196 MethodSwizzling[20966:1866151] 加载失败 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /MethodSwizzling/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MethodSwizzling 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ObjectArchive/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ObjectArchive 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ObjectArchive/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ObjectArchive 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ObjectArchive/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /ObjectArchive/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 | -------------------------------------------------------------------------------- /ObjectArchive/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 | 27 | 28 | 29 | 37 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /ObjectArchive/Cat.h: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Cat : NSObject 12 | 13 | @property (nonatomic, copy) NSString *name; 14 | 15 | - (NSArray *)ignoredNames; 16 | 17 | - (instancetype)initWithCoder:(NSCoder *)aDecoder; 18 | - (void)encodeWithCoder:(NSCoder *)aCoder; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ObjectArchive/Cat.m: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "Cat.h" 10 | 11 | #import "NSObject+Archive.h" 12 | 13 | @implementation Cat 14 | 15 | - (NSArray *)ignoredNames { 16 | return @[]; 17 | } 18 | 19 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 20 | if (self = [super init]) { 21 | [self tuc_initWithCoder:aDecoder]; 22 | } 23 | return self; 24 | } 25 | 26 | - (void)encodeWithCoder:(NSCoder *)aCoder { 27 | [self tuc_encodeWithCoder:aCoder]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /ObjectArchive/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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ObjectArchive/NSObject+Archive.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Archive.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (Archive) 12 | 13 | - (NSArray *)ignoredProperty; 14 | 15 | - (void)tuc_encodeWithCoder:(NSCoder *)aCoder; 16 | - (void)tuc_initWithCoder:(NSCoder *)aDecoder; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ObjectArchive/NSObject+Archive.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Archive.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "NSObject+Archive.h" 10 | 11 | #import 12 | 13 | @implementation NSObject (Archive) 14 | 15 | - (NSArray *)ignoredProperty { 16 | return @[]; 17 | } 18 | 19 | - (void)tuc_initWithCoder:(NSCoder *)aDecoder { 20 | // 不光归档自身的属性,还要循环把所有父类的属性也找出来 21 | Class selfClass = self.class; 22 | while (selfClass &&selfClass != [NSObject class]) { 23 | 24 | unsigned int outCount = 0; 25 | Ivar *ivars = class_copyIvarList(selfClass, &outCount); 26 | for (int i = 0; i < outCount; i++) { 27 | Ivar ivar = ivars[i]; 28 | NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; 29 | 30 | // 如果有实现忽略属性的方法 31 | if ([self respondsToSelector:@selector(ignoredProperty)]) { 32 | // 就跳过这个属性 33 | if ([[self ignoredProperty] containsObject:key]) continue; 34 | } 35 | 36 | id value = [aDecoder decodeObjectForKey:key]; 37 | [self setValue:value forKey:key]; 38 | } 39 | free(ivars); 40 | selfClass = [selfClass superclass]; 41 | } 42 | 43 | } 44 | 45 | - (void)tuc_encodeWithCoder:(NSCoder *)aCoder { 46 | Class selfClass = self.class; 47 | while (selfClass &&selfClass != [NSObject class]) { 48 | 49 | unsigned int outCount = 0; 50 | Ivar *ivars = class_copyIvarList([self class], &outCount); 51 | for (int i = 0; i < outCount; i++) { 52 | Ivar ivar = ivars[i]; 53 | NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; 54 | 55 | if ([self respondsToSelector:@selector(ignoredProperty)]) { 56 | if ([[self ignoredProperty] containsObject:key]) continue; 57 | } 58 | 59 | id value = [self valueForKeyPath:key]; 60 | [aCoder encodeObject:value forKey:key]; 61 | } 62 | free(ivars); 63 | selfClass = [selfClass superclass]; 64 | } 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /ObjectArchive/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ObjectArchive 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ObjectArchive/ViewController.m: -------------------------------------------------------------------------------- 1 | // RuntimeSummary - 一个集合了常用 Objective-C Runtime 用法的 Playground 2 | // https://github.com/Tuccuay/RuntimeSummary 3 | 4 | // ObjectArchive / 对象归档、解档 5 | 6 | #import "ViewController.h" 7 | 8 | #import "Cat.h" 9 | 10 | @interface ViewController () 11 | 12 | @property (nonatomic, strong) Cat *anCat; 13 | @property (nonatomic, copy) NSString *path; 14 | 15 | @property (weak, nonatomic) IBOutlet UITextField *textField; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.path = NSHomeDirectory(); 25 | self.path = [NSString stringWithFormat:@"%@/anCat", self.path]; 26 | 27 | self.anCat = [NSKeyedUnarchiver unarchiveObjectWithFile:self.path]; 28 | 29 | if (!self.anCat) { 30 | self.anCat = [[Cat alloc] init]; 31 | } 32 | 33 | self.textField.text = self.anCat.name; 34 | } 35 | 36 | - (IBAction)saveButtonClicked:(UIButton *)sender { 37 | self.anCat.name = self.textField.text; 38 | 39 | [NSKeyedArchiver archiveRootObject:self.anCat toFile:self.path]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ObjectArchive/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ObjectArchive 4 | // 5 | // Created by 朔 洪 on 16/4/24. 6 | // Copyright © 2016年 Tuccuay. 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 | ![RuntimeSummary](https://github.com/Tuccuay/RuntimeSummary/raw/master/Assets/RuntimeSummary.png) 2 | 3 | # RuntimeSummary 4 | 一个集合了常用 Objective-C Runtime 使用方法的 Playground 5 | 6 | ## 目录 7 | 8 | * [如何使用这个 Playground](#Playground) 9 | * [消息机制介绍 / Messaging](#Messaging) 10 | * [方法交换 / MethodSwizzling](#MethodSwizzling) 11 | * [动态加载方法 / ResolveInstanceMethod](#ResolveInstanceMethod) 12 | * [消息转发 / ForwardMessage](#ForwardMessage) 13 | * [动态关联属性 / AssociatedObject](#AssociatedObject) 14 | * [字典转模型 / MakeModel](#MakeModel) 15 | * [对象归档、解档 / ObjectArchive](#ObjectArchive) 16 | * [更多](#More) 17 | 18 |

如何使用这个 Playground

19 | 20 | ![Screenshot](https://github.com/Tuccuay/RuntimeSummary/raw/master/Assets/Screenshot.png) 21 | 22 | 先选择 Scheme,然后 Run! 23 | 24 |

消息机制介绍 / Messaging

25 | 26 | ```objc 27 | // 创建一个对象 28 | // Cat *harlan = [[Cat alloc] init]; 29 | 30 | // 使用 Runtime 创建一个对象 31 | // 根据类名获取到类 32 | Class catClass = objc_getClass("Cat"); 33 | 34 | // 同过类创建实例对象 35 | // 如果这里报错,请将 Build Setting -> Enable Strict Checking of objc_msgSend Calls 改为 NO 36 | Cat *harlan = objc_msgSend(catClass, @selector(alloc)); 37 | 38 | // 初始化对象 39 | // harlan = [harlan init]; 40 | 41 | // 通过 Runtime 初始化对象 42 | harlan = objc_msgSend(harlan, @selector(init)); 43 | 44 | // 调用对象方法 45 | // [harlan eat]; 46 | 47 | // 通过 Runtime 调用对象方法 48 | // 调用的这个方法没有声明只有实现所以这里会有警告 49 | // 但是发送消息的时候会从方法列表里寻找方法 50 | // 所以这个能够成功执行 51 | objc_msgSend(harlan, @selector(eat)); 52 | 53 | // 输出: 2016-04-21 21:10:20.733 Messaging[20696:1825249] burbur~ 54 | 55 | // 当然,objc_msgSend 可以传递参数 56 | Cat *alex = objc_msgSend(objc_msgSend(objc_getClass("Cat"), sel_registerName("alloc")), sel_registerName("init")); 57 | objc_msgSend(alex, @selector(run:), 10); 58 | ``` 59 | 60 |

方法交换 / MethodSwizzling

61 | 62 | ```objc 63 | + (void)load { 64 | // 获取到两个方法 65 | Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:)); 66 | Method tuc_imageNamedMethod = class_getClassMethod(self, @selector(tuc_imageNamed:)); 67 | 68 | // 交换方法 69 | method_exchangeImplementations(imageNamedMethod, tuc_imageNamedMethod); 70 | } 71 | 72 | + (UIImage *)tuc_imageNamed:(NSString *)name { 73 | // 因为来到这里的时候方法实际上已经被交换过了 74 | // 这里要调用 imageNamed: 就需要调换被交换过的 tuc_imageNamed 75 | UIImage *image = [UIImage tuc_imageNamed:name]; 76 | 77 | // 判断是否存在图片 78 | if (image) { 79 | NSLog(@"加载成功"); 80 | } else { 81 | NSLog(@"加载失败"); 82 | } 83 | 84 | return image; 85 | } 86 | ``` 87 | 88 |

动态加载方法 / ResolveInstanceMethod

89 | 90 | ```objc 91 | void run(id self, SEL _cmd, NSNumber *metre) { 92 | NSLog(@"跑了%@米",metre); 93 | } 94 | 95 | // 当调用了一个未实现的方法会来到这里 96 | + (BOOL)resolveInstanceMethod:(SEL)sel { 97 | if (sel == NSSelectorFromString(@"run:")) { 98 | // 动态添加 run: 方法 99 | class_addMethod(self, @selector(run:), run, "v@:@"); 100 | 101 | return YES; 102 | } 103 | 104 | return [super resolveInstanceMethod:sel]; 105 | } 106 | ``` 107 | 108 |

消息转发 / ForwardMessage

109 | 110 | ```objc 111 | #pragma mark - 实例方法 112 | 113 | // 第一步 114 | // 在没有找到方法时,会先调用此方法,可用于动态添加方法 115 | // 返回 YES 表示相应 selector 的实现已经被找到并添加到了类中,否则返回 NO 116 | 117 | + (BOOL)resolveInstanceMethod:(SEL)sel { 118 | return YES; 119 | } 120 | 121 | // 第二步 122 | // 如果第一步的返回 NO 或者直接返回了 YES 而没有添加方法,该方法被调用 123 | // 在这个方法中,我们可以指定一个可以返回一个可以响应该方法的对象 124 | // 如果返回 self 就会死循环 125 | 126 | - (id)forwardingTargetForSelector:(SEL)aSelector { 127 | return nil; 128 | } 129 | 130 | // 第三步 131 | // 如果 `forwardingTargetForSelector:` 返回了 nil,则该方法会被调用,系统会询问我们要一个合法的『类型编码(Type Encoding)』 132 | // https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html 133 | // 若返回 nil,则不会进入下一步,而是无法处理消息 134 | 135 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 136 | return [NSMethodSignature signatureWithObjCTypes:"v@:"]; 137 | } 138 | 139 | // 当实现了此方法后,-doesNotRecognizeSelector: 将不会被调用 140 | // 如果要测试找不到方法,可以注释掉这一个方法 141 | // 在这里进行消息转发 142 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 143 | // 我们还可以改变方法选择器 144 | [anInvocation setSelector:@selector(touch)]; 145 | // 改变方法选择器后,还需要指定是哪个对象的方法 146 | [anInvocation invokeWithTarget:self]; 147 | } 148 | 149 | - (void)touch { 150 | NSLog(@"Cat 没有实现 -stoke 方法,并且成功的转成了 -touch 方法"); 151 | } 152 | 153 | - (void)doesNotRecognizeSelector:(SEL)aSelector { 154 | NSLog(@"无法处理消息:%@", NSStringFromSelector(aSelector)); 155 | } 156 | ``` 157 | 158 |

动态关联属性 / AssociatedObject

159 | 160 | ```objc 161 | - (void)setName:(NSString *)name { 162 | // 把属性关联给对象 163 | objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 164 | } 165 | 166 | - (NSString *)name { 167 | // 取出属性 168 | return objc_getAssociatedObject(self, "name"); 169 | } 170 | ``` 171 | 172 |

字典转模型 / MakeModel

173 | 174 | ```objc 175 | + (instancetype)modelWithDict:(NSDictionary *)dict updateDict:(NSDictionary *)updateDict { 176 | id model = [[self alloc] init]; 177 | // 遍历模型中属性 178 | unsigned int count = 0; 179 | Ivar *ivars = class_copyIvarList(self, &count); 180 | for (int i = 0 ; i < count; i++) { 181 | Ivar ivar = ivars[i]; 182 | // 属性名称 183 | NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)]; 184 | ivarName = [ivarName substringFromIndex:1]; 185 | id value = dict[ivarName]; 186 | // 模型中属性名对应字典中的key 187 | if (value == nil) { 188 | if (updateDict) { 189 | NSString *keyName = updateDict[ivarName]; 190 | value = dict[keyName]; 191 | } 192 | } 193 | [model setValue:value forKeyPath:ivarName]; 194 | } 195 | return model; 196 | } 197 | 198 | + (instancetype)modelWithDict:(NSDictionary *)dict { 199 | return [self modelWithDict:dict updateDict:nil]; 200 | } 201 | ``` 202 | 203 |

对象归档、解档 / ObjectArchive

204 | 205 | ```objc 206 | - (void)tuc_initWithCoder:(NSCoder *)aDecoder { 207 | // 不光归档自身的属性,还要循环把所有父类的属性也找出来 208 | Class selfClass = self.class; 209 | while (selfClass &&selfClass != [NSObject class]) { 210 | 211 | unsigned int outCount = 0; 212 | Ivar *ivars = class_copyIvarList(selfClass, &outCount); 213 | for (int i = 0; i < outCount; i++) { 214 | Ivar ivar = ivars[i]; 215 | NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; 216 | 217 | // 如果有实现忽略属性的方法 218 | if ([self respondsToSelector:@selector(ignoredProperty)]) { 219 | // 就跳过这个属性 220 | if ([[self ignoredProperty] containsObject:key]) continue; 221 | } 222 | 223 | id value = [aDecoder decodeObjectForKey:key]; 224 | [self setValue:value forKey:key]; 225 | } 226 | free(ivars); 227 | selfClass = [selfClass superclass]; 228 | } 229 | 230 | } 231 | 232 | - (void)tuc_encodeWithCoder:(NSCoder *)aCoder { 233 | Class selfClass = self.class; 234 | while (selfClass &&selfClass != [NSObject class]) { 235 | 236 | unsigned int outCount = 0; 237 | Ivar *ivars = class_copyIvarList([self class], &outCount); 238 | for (int i = 0; i < outCount; i++) { 239 | Ivar ivar = ivars[i]; 240 | NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; 241 | 242 | if ([self respondsToSelector:@selector(ignoredProperty)]) { 243 | if ([[self ignoredProperty] containsObject:key]) continue; 244 | } 245 | 246 | id value = [self valueForKeyPath:key]; 247 | [aCoder encodeObject:value forKey:key]; 248 | } 249 | free(ivars); 250 | selfClass = [selfClass superclass]; 251 | } 252 | } 253 | ``` 254 | 255 |

更多

256 | 257 | 觉得还有其它常用的 Runtime 用法没有讲到?欢迎 Pull Request! 258 | 259 | 或者懒得动手想看看大家的思路?没问题,提个 [issue](https://github.com/Tuccuay/RuntimeSummary/issues/new) ! 260 | 261 | 觉得看了这个 Playground 豁然开朗?来 Star 一个吧! 262 | 263 | ## License 264 | 265 | RuntimeSummary is released under the MIT license. See [LICENSE](https://github.com/Tuccuay/RuntimeSummary/blob/master/LICENSE) . 266 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ResolveInstanceMethod 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ResolveInstanceMethod 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /ResolveInstanceMethod/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 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/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 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/Cat.h: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.h 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Cat : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/Cat.m: -------------------------------------------------------------------------------- 1 | // 2 | // Cat.m 3 | // RuntimeSummary 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import "Cat.h" 10 | 11 | #import 12 | 13 | @implementation Cat 14 | 15 | void run(id self, SEL _cmd, NSNumber *metre) { 16 | NSLog(@"跑了%@米",metre); 17 | } 18 | 19 | // 当调用了一个未实现的方法会来到这里 20 | + (BOOL)resolveInstanceMethod:(SEL)sel { 21 | if (sel == NSSelectorFromString(@"run:")) { 22 | // 动态添加 run: 方法 23 | class_addMethod(self, @selector(run:), run, "v@:@"); 24 | 25 | return YES; 26 | } 27 | 28 | return [super resolveInstanceMethod:sel]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/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 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ResolveInstanceMethod 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/ViewController.m: -------------------------------------------------------------------------------- 1 | // RuntimeSummary - 一个集合了常用 Objective-C Runtime 用法的 Playground 2 | // https://github.com/Tuccuay/RuntimeSummary 3 | 4 | // ResolveInstanceMethod / 动态加载方法 5 | 6 | #import "ViewController.h" 7 | 8 | #import "Cat.h" 9 | 10 | @interface ViewController () 11 | 12 | @end 13 | 14 | @implementation ViewController 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | 19 | Cat *billy = [[Cat alloc] init]; 20 | 21 | // 这个时候 billy 对象并没有 run: 方法 22 | // 所以会进入 + (BOOL)resolveClassMethod:(SEL)sel 处理 23 | // 然后方法被动态添加 24 | [billy performSelector:@selector(run:) withObject:@10]; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /ResolveInstanceMethod/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ResolveInstanceMethod 4 | // 5 | // Created by 朔 洪 on 16/4/21. 6 | // Copyright © 2016年 Tuccuay. 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 | -------------------------------------------------------------------------------- /RuntimeSummary.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DF1FFB0D1CCBC1D600E967B9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB0C1CCBC1D600E967B9 /* main.m */; }; 11 | DF1FFB101CCBC1D600E967B9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB0F1CCBC1D600E967B9 /* AppDelegate.m */; }; 12 | DF1FFB131CCBC1D600E967B9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB121CCBC1D600E967B9 /* ViewController.m */; }; 13 | DF1FFB161CCBC1D600E967B9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF1FFB141CCBC1D600E967B9 /* Main.storyboard */; }; 14 | DF1FFB181CCBC1D600E967B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DF1FFB171CCBC1D600E967B9 /* Assets.xcassets */; }; 15 | DF1FFB1B1CCBC1D600E967B9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF1FFB191CCBC1D600E967B9 /* LaunchScreen.storyboard */; }; 16 | DF1FFB221CCBC20900E967B9 /* Cat.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB211CCBC20900E967B9 /* Cat.m */; }; 17 | DF1FFB2B1CCBE36800E967B9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB2A1CCBE36800E967B9 /* main.m */; }; 18 | DF1FFB2E1CCBE36800E967B9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB2D1CCBE36800E967B9 /* AppDelegate.m */; }; 19 | DF1FFB311CCBE36800E967B9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB301CCBE36800E967B9 /* ViewController.m */; }; 20 | DF1FFB341CCBE36800E967B9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF1FFB321CCBE36800E967B9 /* Main.storyboard */; }; 21 | DF1FFB361CCBE36800E967B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DF1FFB351CCBE36800E967B9 /* Assets.xcassets */; }; 22 | DF1FFB391CCBE36800E967B9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF1FFB371CCBE36800E967B9 /* LaunchScreen.storyboard */; }; 23 | DF1FFB401CCBE38800E967B9 /* NSObject+Archive.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB3F1CCBE38800E967B9 /* NSObject+Archive.m */; }; 24 | DF1FFB431CCBE76700E967B9 /* Cat.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1FFB421CCBE76700E967B9 /* Cat.m */; }; 25 | DF6D03AA1CCB6B9C006D70F0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DF6D03A91CCB6B9C006D70F0 /* main.m */; }; 26 | DF6D03AD1CCB6B9C006D70F0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DF6D03AC1CCB6B9C006D70F0 /* AppDelegate.m */; }; 27 | DF6D03B01CCB6B9C006D70F0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DF6D03AF1CCB6B9C006D70F0 /* ViewController.m */; }; 28 | DF6D03B31CCB6B9C006D70F0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF6D03B11CCB6B9C006D70F0 /* Main.storyboard */; }; 29 | DF6D03B51CCB6B9C006D70F0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DF6D03B41CCB6B9C006D70F0 /* Assets.xcassets */; }; 30 | DF6D03B81CCB6B9C006D70F0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF6D03B61CCB6B9C006D70F0 /* LaunchScreen.storyboard */; }; 31 | DF6D03BF1CCB6C18006D70F0 /* GithubUser.m in Sources */ = {isa = PBXBuildFile; fileRef = DF6D03BE1CCB6C18006D70F0 /* GithubUser.m */; }; 32 | DF6D03C51CCBB931006D70F0 /* NSObject+Model.m in Sources */ = {isa = PBXBuildFile; fileRef = DF6D03C41CCBB931006D70F0 /* NSObject+Model.m */; }; 33 | DFC63A0A1CC8FFF200500187 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A091CC8FFF200500187 /* main.m */; }; 34 | DFC63A0D1CC8FFF200500187 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A0C1CC8FFF200500187 /* AppDelegate.m */; }; 35 | DFC63A101CC8FFF200500187 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A0F1CC8FFF200500187 /* ViewController.m */; }; 36 | DFC63A131CC8FFF200500187 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A111CC8FFF200500187 /* Main.storyboard */; }; 37 | DFC63A151CC8FFF200500187 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A141CC8FFF200500187 /* Assets.xcassets */; }; 38 | DFC63A181CC8FFF200500187 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A161CC8FFF200500187 /* LaunchScreen.storyboard */; }; 39 | DFC63A1F1CC900BE00500187 /* Cat.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A1E1CC900BE00500187 /* Cat.m */; }; 40 | DFC63A281CC90C9700500187 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A271CC90C9700500187 /* main.m */; }; 41 | DFC63A2B1CC90C9700500187 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A2A1CC90C9700500187 /* AppDelegate.m */; }; 42 | DFC63A2E1CC90C9700500187 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A2D1CC90C9700500187 /* ViewController.m */; }; 43 | DFC63A311CC90C9700500187 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A2F1CC90C9700500187 /* Main.storyboard */; }; 44 | DFC63A331CC90C9700500187 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A321CC90C9700500187 /* Assets.xcassets */; }; 45 | DFC63A361CC90C9700500187 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A341CC90C9700500187 /* LaunchScreen.storyboard */; }; 46 | DFC63A3D1CC90DAD00500187 /* UIImage+Success.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A3C1CC90DAD00500187 /* UIImage+Success.m */; }; 47 | DFC63A461CC9115000500187 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A451CC9115000500187 /* main.m */; }; 48 | DFC63A491CC9115000500187 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A481CC9115000500187 /* AppDelegate.m */; }; 49 | DFC63A4C1CC9115000500187 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A4B1CC9115000500187 /* ViewController.m */; }; 50 | DFC63A4F1CC9115000500187 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A4D1CC9115000500187 /* Main.storyboard */; }; 51 | DFC63A511CC9115000500187 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A501CC9115000500187 /* Assets.xcassets */; }; 52 | DFC63A541CC9115000500187 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A521CC9115000500187 /* LaunchScreen.storyboard */; }; 53 | DFC63A5B1CC9118A00500187 /* Cat.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A5A1CC9118A00500187 /* Cat.m */; }; 54 | DFC63A641CC9159400500187 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A631CC9159400500187 /* main.m */; }; 55 | DFC63A671CC9159400500187 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A661CC9159400500187 /* AppDelegate.m */; }; 56 | DFC63A6A1CC9159400500187 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A691CC9159400500187 /* ViewController.m */; }; 57 | DFC63A6D1CC9159400500187 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A6B1CC9159400500187 /* Main.storyboard */; }; 58 | DFC63A6F1CC9159400500187 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A6E1CC9159400500187 /* Assets.xcassets */; }; 59 | DFC63A721CC9159400500187 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DFC63A701CC9159400500187 /* LaunchScreen.storyboard */; }; 60 | DFC63A791CC9166A00500187 /* NSObject+Property.m in Sources */ = {isa = PBXBuildFile; fileRef = DFC63A781CC9166A00500187 /* NSObject+Property.m */; }; 61 | /* End PBXBuildFile section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | DF1FFB091CCBC1D600E967B9 /* ForwardMessage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ForwardMessage.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | DF1FFB0C1CCBC1D600E967B9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 66 | DF1FFB0E1CCBC1D600E967B9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 67 | DF1FFB0F1CCBC1D600E967B9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 68 | DF1FFB111CCBC1D600E967B9 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 69 | DF1FFB121CCBC1D600E967B9 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 70 | DF1FFB151CCBC1D600E967B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 71 | DF1FFB171CCBC1D600E967B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 72 | DF1FFB1A1CCBC1D600E967B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 73 | DF1FFB1C1CCBC1D600E967B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | DF1FFB201CCBC20900E967B9 /* Cat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cat.h; sourceTree = ""; }; 75 | DF1FFB211CCBC20900E967B9 /* Cat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Cat.m; sourceTree = ""; }; 76 | DF1FFB271CCBE36800E967B9 /* ObjectArchive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ObjectArchive.app; sourceTree = BUILT_PRODUCTS_DIR; }; 77 | DF1FFB2A1CCBE36800E967B9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 78 | DF1FFB2C1CCBE36800E967B9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 79 | DF1FFB2D1CCBE36800E967B9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 80 | DF1FFB2F1CCBE36800E967B9 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 81 | DF1FFB301CCBE36800E967B9 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 82 | DF1FFB331CCBE36800E967B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 83 | DF1FFB351CCBE36800E967B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 84 | DF1FFB381CCBE36800E967B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 85 | DF1FFB3A1CCBE36800E967B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 86 | DF1FFB3E1CCBE38800E967B9 /* NSObject+Archive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Archive.h"; sourceTree = ""; }; 87 | DF1FFB3F1CCBE38800E967B9 /* NSObject+Archive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Archive.m"; sourceTree = ""; }; 88 | DF1FFB411CCBE76700E967B9 /* Cat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cat.h; sourceTree = ""; }; 89 | DF1FFB421CCBE76700E967B9 /* Cat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Cat.m; sourceTree = ""; }; 90 | DF6D03A61CCB6B9C006D70F0 /* MakeModel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MakeModel.app; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | DF6D03A91CCB6B9C006D70F0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 92 | DF6D03AB1CCB6B9C006D70F0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 93 | DF6D03AC1CCB6B9C006D70F0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 94 | DF6D03AE1CCB6B9C006D70F0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 95 | DF6D03AF1CCB6B9C006D70F0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 96 | DF6D03B21CCB6B9C006D70F0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97 | DF6D03B41CCB6B9C006D70F0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 98 | DF6D03B71CCB6B9C006D70F0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 99 | DF6D03B91CCB6B9C006D70F0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 100 | DF6D03BD1CCB6C18006D70F0 /* GithubUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GithubUser.h; sourceTree = ""; }; 101 | DF6D03BE1CCB6C18006D70F0 /* GithubUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GithubUser.m; sourceTree = ""; }; 102 | DF6D03C31CCBB931006D70F0 /* NSObject+Model.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Model.h"; sourceTree = ""; }; 103 | DF6D03C41CCBB931006D70F0 /* NSObject+Model.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Model.m"; sourceTree = ""; }; 104 | DFC63A061CC8FFF200500187 /* Messaging.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Messaging.app; sourceTree = BUILT_PRODUCTS_DIR; }; 105 | DFC63A091CC8FFF200500187 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 106 | DFC63A0B1CC8FFF200500187 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 107 | DFC63A0C1CC8FFF200500187 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 108 | DFC63A0E1CC8FFF200500187 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 109 | DFC63A0F1CC8FFF200500187 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 110 | DFC63A121CC8FFF200500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 111 | DFC63A141CC8FFF200500187 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 112 | DFC63A171CC8FFF200500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 113 | DFC63A191CC8FFF200500187 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 114 | DFC63A1D1CC900BE00500187 /* Cat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cat.h; sourceTree = ""; }; 115 | DFC63A1E1CC900BE00500187 /* Cat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Cat.m; sourceTree = ""; }; 116 | DFC63A241CC90C9700500187 /* MethodSwizzling.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MethodSwizzling.app; sourceTree = BUILT_PRODUCTS_DIR; }; 117 | DFC63A271CC90C9700500187 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 118 | DFC63A291CC90C9700500187 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 119 | DFC63A2A1CC90C9700500187 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 120 | DFC63A2C1CC90C9700500187 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 121 | DFC63A2D1CC90C9700500187 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 122 | DFC63A301CC90C9700500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 123 | DFC63A321CC90C9700500187 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 124 | DFC63A351CC90C9700500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 125 | DFC63A371CC90C9700500187 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 126 | DFC63A3B1CC90DAD00500187 /* UIImage+Success.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Success.h"; sourceTree = ""; }; 127 | DFC63A3C1CC90DAD00500187 /* UIImage+Success.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Success.m"; sourceTree = ""; }; 128 | DFC63A421CC9115000500187 /* ResolveInstanceMethod.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ResolveInstanceMethod.app; sourceTree = BUILT_PRODUCTS_DIR; }; 129 | DFC63A451CC9115000500187 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 130 | DFC63A471CC9115000500187 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 131 | DFC63A481CC9115000500187 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 132 | DFC63A4A1CC9115000500187 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 133 | DFC63A4B1CC9115000500187 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 134 | DFC63A4E1CC9115000500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 135 | DFC63A501CC9115000500187 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 136 | DFC63A531CC9115000500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 137 | DFC63A551CC9115100500187 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 138 | DFC63A591CC9118A00500187 /* Cat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cat.h; sourceTree = ""; }; 139 | DFC63A5A1CC9118A00500187 /* Cat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Cat.m; sourceTree = ""; }; 140 | DFC63A601CC9159400500187 /* AssociatedObject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AssociatedObject.app; sourceTree = BUILT_PRODUCTS_DIR; }; 141 | DFC63A631CC9159400500187 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 142 | DFC63A651CC9159400500187 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 143 | DFC63A661CC9159400500187 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 144 | DFC63A681CC9159400500187 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 145 | DFC63A691CC9159400500187 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 146 | DFC63A6C1CC9159400500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 147 | DFC63A6E1CC9159400500187 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 148 | DFC63A711CC9159400500187 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 149 | DFC63A731CC9159400500187 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 150 | DFC63A771CC9166A00500187 /* NSObject+Property.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Property.h"; sourceTree = ""; }; 151 | DFC63A781CC9166A00500187 /* NSObject+Property.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Property.m"; sourceTree = ""; }; 152 | /* End PBXFileReference section */ 153 | 154 | /* Begin PBXFrameworksBuildPhase section */ 155 | DF1FFB061CCBC1D600E967B9 /* Frameworks */ = { 156 | isa = PBXFrameworksBuildPhase; 157 | buildActionMask = 2147483647; 158 | files = ( 159 | ); 160 | runOnlyForDeploymentPostprocessing = 0; 161 | }; 162 | DF1FFB241CCBE36800E967B9 /* Frameworks */ = { 163 | isa = PBXFrameworksBuildPhase; 164 | buildActionMask = 2147483647; 165 | files = ( 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | DF6D03A31CCB6B9C006D70F0 /* Frameworks */ = { 170 | isa = PBXFrameworksBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | ); 174 | runOnlyForDeploymentPostprocessing = 0; 175 | }; 176 | DFC63A031CC8FFF200500187 /* Frameworks */ = { 177 | isa = PBXFrameworksBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | }; 183 | DFC63A211CC90C9700500187 /* Frameworks */ = { 184 | isa = PBXFrameworksBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | ); 188 | runOnlyForDeploymentPostprocessing = 0; 189 | }; 190 | DFC63A3F1CC9115000500187 /* Frameworks */ = { 191 | isa = PBXFrameworksBuildPhase; 192 | buildActionMask = 2147483647; 193 | files = ( 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | DFC63A5D1CC9159400500187 /* Frameworks */ = { 198 | isa = PBXFrameworksBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXFrameworksBuildPhase section */ 205 | 206 | /* Begin PBXGroup section */ 207 | DF1FFB0A1CCBC1D600E967B9 /* ForwardMessage */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | DF1FFB0E1CCBC1D600E967B9 /* AppDelegate.h */, 211 | DF1FFB0F1CCBC1D600E967B9 /* AppDelegate.m */, 212 | DF1FFB111CCBC1D600E967B9 /* ViewController.h */, 213 | DF1FFB121CCBC1D600E967B9 /* ViewController.m */, 214 | DF1FFB201CCBC20900E967B9 /* Cat.h */, 215 | DF1FFB211CCBC20900E967B9 /* Cat.m */, 216 | DF1FFB141CCBC1D600E967B9 /* Main.storyboard */, 217 | DF1FFB171CCBC1D600E967B9 /* Assets.xcassets */, 218 | DF1FFB191CCBC1D600E967B9 /* LaunchScreen.storyboard */, 219 | DF1FFB1C1CCBC1D600E967B9 /* Info.plist */, 220 | DF1FFB0B1CCBC1D600E967B9 /* Supporting Files */, 221 | ); 222 | path = ForwardMessage; 223 | sourceTree = ""; 224 | }; 225 | DF1FFB0B1CCBC1D600E967B9 /* Supporting Files */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | DF1FFB0C1CCBC1D600E967B9 /* main.m */, 229 | ); 230 | name = "Supporting Files"; 231 | sourceTree = ""; 232 | }; 233 | DF1FFB281CCBE36800E967B9 /* ObjectArchive */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | DF1FFB2C1CCBE36800E967B9 /* AppDelegate.h */, 237 | DF1FFB2D1CCBE36800E967B9 /* AppDelegate.m */, 238 | DF1FFB2F1CCBE36800E967B9 /* ViewController.h */, 239 | DF1FFB301CCBE36800E967B9 /* ViewController.m */, 240 | DF1FFB411CCBE76700E967B9 /* Cat.h */, 241 | DF1FFB421CCBE76700E967B9 /* Cat.m */, 242 | DF1FFB3E1CCBE38800E967B9 /* NSObject+Archive.h */, 243 | DF1FFB3F1CCBE38800E967B9 /* NSObject+Archive.m */, 244 | DF1FFB321CCBE36800E967B9 /* Main.storyboard */, 245 | DF1FFB351CCBE36800E967B9 /* Assets.xcassets */, 246 | DF1FFB371CCBE36800E967B9 /* LaunchScreen.storyboard */, 247 | DF1FFB3A1CCBE36800E967B9 /* Info.plist */, 248 | DF1FFB291CCBE36800E967B9 /* Supporting Files */, 249 | ); 250 | path = ObjectArchive; 251 | sourceTree = ""; 252 | }; 253 | DF1FFB291CCBE36800E967B9 /* Supporting Files */ = { 254 | isa = PBXGroup; 255 | children = ( 256 | DF1FFB2A1CCBE36800E967B9 /* main.m */, 257 | ); 258 | name = "Supporting Files"; 259 | sourceTree = ""; 260 | }; 261 | DF6D03A71CCB6B9C006D70F0 /* MakeModel */ = { 262 | isa = PBXGroup; 263 | children = ( 264 | DF6D03AB1CCB6B9C006D70F0 /* AppDelegate.h */, 265 | DF6D03AC1CCB6B9C006D70F0 /* AppDelegate.m */, 266 | DF6D03AE1CCB6B9C006D70F0 /* ViewController.h */, 267 | DF6D03AF1CCB6B9C006D70F0 /* ViewController.m */, 268 | DF6D03BD1CCB6C18006D70F0 /* GithubUser.h */, 269 | DF6D03BE1CCB6C18006D70F0 /* GithubUser.m */, 270 | DF6D03C31CCBB931006D70F0 /* NSObject+Model.h */, 271 | DF6D03C41CCBB931006D70F0 /* NSObject+Model.m */, 272 | DF6D03B11CCB6B9C006D70F0 /* Main.storyboard */, 273 | DF6D03B41CCB6B9C006D70F0 /* Assets.xcassets */, 274 | DF6D03B61CCB6B9C006D70F0 /* LaunchScreen.storyboard */, 275 | DF6D03B91CCB6B9C006D70F0 /* Info.plist */, 276 | DF6D03A81CCB6B9C006D70F0 /* Supporting Files */, 277 | ); 278 | path = MakeModel; 279 | sourceTree = ""; 280 | }; 281 | DF6D03A81CCB6B9C006D70F0 /* Supporting Files */ = { 282 | isa = PBXGroup; 283 | children = ( 284 | DF6D03A91CCB6B9C006D70F0 /* main.m */, 285 | ); 286 | name = "Supporting Files"; 287 | sourceTree = ""; 288 | }; 289 | DFC639C11CC8F2A000500187 = { 290 | isa = PBXGroup; 291 | children = ( 292 | DFC63A071CC8FFF200500187 /* Messaging */, 293 | DFC63A251CC90C9700500187 /* MethodSwizzling */, 294 | DFC63A431CC9115000500187 /* ResolveInstanceMethod */, 295 | DF1FFB0A1CCBC1D600E967B9 /* ForwardMessage */, 296 | DFC63A611CC9159400500187 /* AssociatedObject */, 297 | DF6D03A71CCB6B9C006D70F0 /* MakeModel */, 298 | DF1FFB281CCBE36800E967B9 /* ObjectArchive */, 299 | DFC639CB1CC8F2A100500187 /* Products */, 300 | ); 301 | sourceTree = ""; 302 | }; 303 | DFC639CB1CC8F2A100500187 /* Products */ = { 304 | isa = PBXGroup; 305 | children = ( 306 | DFC63A061CC8FFF200500187 /* Messaging.app */, 307 | DFC63A241CC90C9700500187 /* MethodSwizzling.app */, 308 | DFC63A421CC9115000500187 /* ResolveInstanceMethod.app */, 309 | DFC63A601CC9159400500187 /* AssociatedObject.app */, 310 | DF6D03A61CCB6B9C006D70F0 /* MakeModel.app */, 311 | DF1FFB091CCBC1D600E967B9 /* ForwardMessage.app */, 312 | DF1FFB271CCBE36800E967B9 /* ObjectArchive.app */, 313 | ); 314 | name = Products; 315 | sourceTree = ""; 316 | }; 317 | DFC63A071CC8FFF200500187 /* Messaging */ = { 318 | isa = PBXGroup; 319 | children = ( 320 | DFC63A0B1CC8FFF200500187 /* AppDelegate.h */, 321 | DFC63A0C1CC8FFF200500187 /* AppDelegate.m */, 322 | DFC63A0E1CC8FFF200500187 /* ViewController.h */, 323 | DFC63A0F1CC8FFF200500187 /* ViewController.m */, 324 | DFC63A1D1CC900BE00500187 /* Cat.h */, 325 | DFC63A1E1CC900BE00500187 /* Cat.m */, 326 | DFC63A111CC8FFF200500187 /* Main.storyboard */, 327 | DFC63A141CC8FFF200500187 /* Assets.xcassets */, 328 | DFC63A161CC8FFF200500187 /* LaunchScreen.storyboard */, 329 | DFC63A191CC8FFF200500187 /* Info.plist */, 330 | DFC63A081CC8FFF200500187 /* Supporting Files */, 331 | ); 332 | path = Messaging; 333 | sourceTree = ""; 334 | }; 335 | DFC63A081CC8FFF200500187 /* Supporting Files */ = { 336 | isa = PBXGroup; 337 | children = ( 338 | DFC63A091CC8FFF200500187 /* main.m */, 339 | ); 340 | name = "Supporting Files"; 341 | sourceTree = ""; 342 | }; 343 | DFC63A251CC90C9700500187 /* MethodSwizzling */ = { 344 | isa = PBXGroup; 345 | children = ( 346 | DFC63A291CC90C9700500187 /* AppDelegate.h */, 347 | DFC63A2A1CC90C9700500187 /* AppDelegate.m */, 348 | DFC63A2C1CC90C9700500187 /* ViewController.h */, 349 | DFC63A2D1CC90C9700500187 /* ViewController.m */, 350 | DFC63A3B1CC90DAD00500187 /* UIImage+Success.h */, 351 | DFC63A3C1CC90DAD00500187 /* UIImage+Success.m */, 352 | DFC63A2F1CC90C9700500187 /* Main.storyboard */, 353 | DFC63A321CC90C9700500187 /* Assets.xcassets */, 354 | DFC63A341CC90C9700500187 /* LaunchScreen.storyboard */, 355 | DFC63A371CC90C9700500187 /* Info.plist */, 356 | DFC63A261CC90C9700500187 /* Supporting Files */, 357 | ); 358 | path = MethodSwizzling; 359 | sourceTree = ""; 360 | }; 361 | DFC63A261CC90C9700500187 /* Supporting Files */ = { 362 | isa = PBXGroup; 363 | children = ( 364 | DFC63A271CC90C9700500187 /* main.m */, 365 | ); 366 | name = "Supporting Files"; 367 | sourceTree = ""; 368 | }; 369 | DFC63A431CC9115000500187 /* ResolveInstanceMethod */ = { 370 | isa = PBXGroup; 371 | children = ( 372 | DFC63A471CC9115000500187 /* AppDelegate.h */, 373 | DFC63A481CC9115000500187 /* AppDelegate.m */, 374 | DFC63A4A1CC9115000500187 /* ViewController.h */, 375 | DFC63A4B1CC9115000500187 /* ViewController.m */, 376 | DFC63A591CC9118A00500187 /* Cat.h */, 377 | DFC63A5A1CC9118A00500187 /* Cat.m */, 378 | DFC63A4D1CC9115000500187 /* Main.storyboard */, 379 | DFC63A501CC9115000500187 /* Assets.xcassets */, 380 | DFC63A521CC9115000500187 /* LaunchScreen.storyboard */, 381 | DFC63A551CC9115100500187 /* Info.plist */, 382 | DFC63A441CC9115000500187 /* Supporting Files */, 383 | ); 384 | path = ResolveInstanceMethod; 385 | sourceTree = ""; 386 | }; 387 | DFC63A441CC9115000500187 /* Supporting Files */ = { 388 | isa = PBXGroup; 389 | children = ( 390 | DFC63A451CC9115000500187 /* main.m */, 391 | ); 392 | name = "Supporting Files"; 393 | sourceTree = ""; 394 | }; 395 | DFC63A611CC9159400500187 /* AssociatedObject */ = { 396 | isa = PBXGroup; 397 | children = ( 398 | DFC63A651CC9159400500187 /* AppDelegate.h */, 399 | DFC63A661CC9159400500187 /* AppDelegate.m */, 400 | DFC63A681CC9159400500187 /* ViewController.h */, 401 | DFC63A691CC9159400500187 /* ViewController.m */, 402 | DFC63A771CC9166A00500187 /* NSObject+Property.h */, 403 | DFC63A781CC9166A00500187 /* NSObject+Property.m */, 404 | DFC63A6B1CC9159400500187 /* Main.storyboard */, 405 | DFC63A6E1CC9159400500187 /* Assets.xcassets */, 406 | DFC63A701CC9159400500187 /* LaunchScreen.storyboard */, 407 | DFC63A731CC9159400500187 /* Info.plist */, 408 | DFC63A621CC9159400500187 /* Supporting Files */, 409 | ); 410 | path = AssociatedObject; 411 | sourceTree = ""; 412 | }; 413 | DFC63A621CC9159400500187 /* Supporting Files */ = { 414 | isa = PBXGroup; 415 | children = ( 416 | DFC63A631CC9159400500187 /* main.m */, 417 | ); 418 | name = "Supporting Files"; 419 | sourceTree = ""; 420 | }; 421 | /* End PBXGroup section */ 422 | 423 | /* Begin PBXNativeTarget section */ 424 | DF1FFB081CCBC1D600E967B9 /* ForwardMessage */ = { 425 | isa = PBXNativeTarget; 426 | buildConfigurationList = DF1FFB1F1CCBC1D600E967B9 /* Build configuration list for PBXNativeTarget "ForwardMessage" */; 427 | buildPhases = ( 428 | DF1FFB051CCBC1D600E967B9 /* Sources */, 429 | DF1FFB061CCBC1D600E967B9 /* Frameworks */, 430 | DF1FFB071CCBC1D600E967B9 /* Resources */, 431 | ); 432 | buildRules = ( 433 | ); 434 | dependencies = ( 435 | ); 436 | name = ForwardMessage; 437 | productName = ForwardMessage; 438 | productReference = DF1FFB091CCBC1D600E967B9 /* ForwardMessage.app */; 439 | productType = "com.apple.product-type.application"; 440 | }; 441 | DF1FFB261CCBE36800E967B9 /* ObjectArchive */ = { 442 | isa = PBXNativeTarget; 443 | buildConfigurationList = DF1FFB3B1CCBE36800E967B9 /* Build configuration list for PBXNativeTarget "ObjectArchive" */; 444 | buildPhases = ( 445 | DF1FFB231CCBE36800E967B9 /* Sources */, 446 | DF1FFB241CCBE36800E967B9 /* Frameworks */, 447 | DF1FFB251CCBE36800E967B9 /* Resources */, 448 | ); 449 | buildRules = ( 450 | ); 451 | dependencies = ( 452 | ); 453 | name = ObjectArchive; 454 | productName = ObjectArchive; 455 | productReference = DF1FFB271CCBE36800E967B9 /* ObjectArchive.app */; 456 | productType = "com.apple.product-type.application"; 457 | }; 458 | DF6D03A51CCB6B9C006D70F0 /* MakeModel */ = { 459 | isa = PBXNativeTarget; 460 | buildConfigurationList = DF6D03BA1CCB6B9C006D70F0 /* Build configuration list for PBXNativeTarget "MakeModel" */; 461 | buildPhases = ( 462 | DF6D03A21CCB6B9C006D70F0 /* Sources */, 463 | DF6D03A31CCB6B9C006D70F0 /* Frameworks */, 464 | DF6D03A41CCB6B9C006D70F0 /* Resources */, 465 | ); 466 | buildRules = ( 467 | ); 468 | dependencies = ( 469 | ); 470 | name = MakeModel; 471 | productName = MakeModel; 472 | productReference = DF6D03A61CCB6B9C006D70F0 /* MakeModel.app */; 473 | productType = "com.apple.product-type.application"; 474 | }; 475 | DFC63A051CC8FFF200500187 /* Messaging */ = { 476 | isa = PBXNativeTarget; 477 | buildConfigurationList = DFC63A1A1CC8FFF300500187 /* Build configuration list for PBXNativeTarget "Messaging" */; 478 | buildPhases = ( 479 | DFC63A021CC8FFF200500187 /* Sources */, 480 | DFC63A031CC8FFF200500187 /* Frameworks */, 481 | DFC63A041CC8FFF200500187 /* Resources */, 482 | ); 483 | buildRules = ( 484 | ); 485 | dependencies = ( 486 | ); 487 | name = Messaging; 488 | productName = Messaging; 489 | productReference = DFC63A061CC8FFF200500187 /* Messaging.app */; 490 | productType = "com.apple.product-type.application"; 491 | }; 492 | DFC63A231CC90C9700500187 /* MethodSwizzling */ = { 493 | isa = PBXNativeTarget; 494 | buildConfigurationList = DFC63A381CC90C9700500187 /* Build configuration list for PBXNativeTarget "MethodSwizzling" */; 495 | buildPhases = ( 496 | DFC63A201CC90C9700500187 /* Sources */, 497 | DFC63A211CC90C9700500187 /* Frameworks */, 498 | DFC63A221CC90C9700500187 /* Resources */, 499 | ); 500 | buildRules = ( 501 | ); 502 | dependencies = ( 503 | ); 504 | name = MethodSwizzling; 505 | productName = MethodSwizzling; 506 | productReference = DFC63A241CC90C9700500187 /* MethodSwizzling.app */; 507 | productType = "com.apple.product-type.application"; 508 | }; 509 | DFC63A411CC9115000500187 /* ResolveInstanceMethod */ = { 510 | isa = PBXNativeTarget; 511 | buildConfigurationList = DFC63A561CC9115100500187 /* Build configuration list for PBXNativeTarget "ResolveInstanceMethod" */; 512 | buildPhases = ( 513 | DFC63A3E1CC9115000500187 /* Sources */, 514 | DFC63A3F1CC9115000500187 /* Frameworks */, 515 | DFC63A401CC9115000500187 /* Resources */, 516 | ); 517 | buildRules = ( 518 | ); 519 | dependencies = ( 520 | ); 521 | name = ResolveInstanceMethod; 522 | productName = ResolveInstanceMethod; 523 | productReference = DFC63A421CC9115000500187 /* ResolveInstanceMethod.app */; 524 | productType = "com.apple.product-type.application"; 525 | }; 526 | DFC63A5F1CC9159400500187 /* AssociatedObject */ = { 527 | isa = PBXNativeTarget; 528 | buildConfigurationList = DFC63A741CC9159400500187 /* Build configuration list for PBXNativeTarget "AssociatedObject" */; 529 | buildPhases = ( 530 | DFC63A5C1CC9159400500187 /* Sources */, 531 | DFC63A5D1CC9159400500187 /* Frameworks */, 532 | DFC63A5E1CC9159400500187 /* Resources */, 533 | ); 534 | buildRules = ( 535 | ); 536 | dependencies = ( 537 | ); 538 | name = AssociatedObject; 539 | productName = AssociatedObject; 540 | productReference = DFC63A601CC9159400500187 /* AssociatedObject.app */; 541 | productType = "com.apple.product-type.application"; 542 | }; 543 | /* End PBXNativeTarget section */ 544 | 545 | /* Begin PBXProject section */ 546 | DFC639C21CC8F2A000500187 /* Project object */ = { 547 | isa = PBXProject; 548 | attributes = { 549 | LastUpgradeCheck = 0730; 550 | ORGANIZATIONNAME = Tuccuay; 551 | TargetAttributes = { 552 | DF1FFB081CCBC1D600E967B9 = { 553 | CreatedOnToolsVersion = 7.3; 554 | }; 555 | DF1FFB261CCBE36800E967B9 = { 556 | CreatedOnToolsVersion = 7.3; 557 | }; 558 | DF6D03A51CCB6B9C006D70F0 = { 559 | CreatedOnToolsVersion = 7.3; 560 | }; 561 | DFC63A051CC8FFF200500187 = { 562 | CreatedOnToolsVersion = 7.3; 563 | }; 564 | DFC63A231CC90C9700500187 = { 565 | CreatedOnToolsVersion = 7.3; 566 | }; 567 | DFC63A411CC9115000500187 = { 568 | CreatedOnToolsVersion = 7.3; 569 | }; 570 | DFC63A5F1CC9159400500187 = { 571 | CreatedOnToolsVersion = 7.3; 572 | }; 573 | }; 574 | }; 575 | buildConfigurationList = DFC639C51CC8F2A000500187 /* Build configuration list for PBXProject "RuntimeSummary" */; 576 | compatibilityVersion = "Xcode 3.2"; 577 | developmentRegion = English; 578 | hasScannedForEncodings = 0; 579 | knownRegions = ( 580 | en, 581 | Base, 582 | ); 583 | mainGroup = DFC639C11CC8F2A000500187; 584 | productRefGroup = DFC639CB1CC8F2A100500187 /* Products */; 585 | projectDirPath = ""; 586 | projectRoot = ""; 587 | targets = ( 588 | DFC63A051CC8FFF200500187 /* Messaging */, 589 | DFC63A231CC90C9700500187 /* MethodSwizzling */, 590 | DFC63A411CC9115000500187 /* ResolveInstanceMethod */, 591 | DFC63A5F1CC9159400500187 /* AssociatedObject */, 592 | DF6D03A51CCB6B9C006D70F0 /* MakeModel */, 593 | DF1FFB081CCBC1D600E967B9 /* ForwardMessage */, 594 | DF1FFB261CCBE36800E967B9 /* ObjectArchive */, 595 | ); 596 | }; 597 | /* End PBXProject section */ 598 | 599 | /* Begin PBXResourcesBuildPhase section */ 600 | DF1FFB071CCBC1D600E967B9 /* Resources */ = { 601 | isa = PBXResourcesBuildPhase; 602 | buildActionMask = 2147483647; 603 | files = ( 604 | DF1FFB1B1CCBC1D600E967B9 /* LaunchScreen.storyboard in Resources */, 605 | DF1FFB181CCBC1D600E967B9 /* Assets.xcassets in Resources */, 606 | DF1FFB161CCBC1D600E967B9 /* Main.storyboard in Resources */, 607 | ); 608 | runOnlyForDeploymentPostprocessing = 0; 609 | }; 610 | DF1FFB251CCBE36800E967B9 /* Resources */ = { 611 | isa = PBXResourcesBuildPhase; 612 | buildActionMask = 2147483647; 613 | files = ( 614 | DF1FFB391CCBE36800E967B9 /* LaunchScreen.storyboard in Resources */, 615 | DF1FFB361CCBE36800E967B9 /* Assets.xcassets in Resources */, 616 | DF1FFB341CCBE36800E967B9 /* Main.storyboard in Resources */, 617 | ); 618 | runOnlyForDeploymentPostprocessing = 0; 619 | }; 620 | DF6D03A41CCB6B9C006D70F0 /* Resources */ = { 621 | isa = PBXResourcesBuildPhase; 622 | buildActionMask = 2147483647; 623 | files = ( 624 | DF6D03B81CCB6B9C006D70F0 /* LaunchScreen.storyboard in Resources */, 625 | DF6D03B51CCB6B9C006D70F0 /* Assets.xcassets in Resources */, 626 | DF6D03B31CCB6B9C006D70F0 /* Main.storyboard in Resources */, 627 | ); 628 | runOnlyForDeploymentPostprocessing = 0; 629 | }; 630 | DFC63A041CC8FFF200500187 /* Resources */ = { 631 | isa = PBXResourcesBuildPhase; 632 | buildActionMask = 2147483647; 633 | files = ( 634 | DFC63A181CC8FFF200500187 /* LaunchScreen.storyboard in Resources */, 635 | DFC63A151CC8FFF200500187 /* Assets.xcassets in Resources */, 636 | DFC63A131CC8FFF200500187 /* Main.storyboard in Resources */, 637 | ); 638 | runOnlyForDeploymentPostprocessing = 0; 639 | }; 640 | DFC63A221CC90C9700500187 /* Resources */ = { 641 | isa = PBXResourcesBuildPhase; 642 | buildActionMask = 2147483647; 643 | files = ( 644 | DFC63A361CC90C9700500187 /* LaunchScreen.storyboard in Resources */, 645 | DFC63A331CC90C9700500187 /* Assets.xcassets in Resources */, 646 | DFC63A311CC90C9700500187 /* Main.storyboard in Resources */, 647 | ); 648 | runOnlyForDeploymentPostprocessing = 0; 649 | }; 650 | DFC63A401CC9115000500187 /* Resources */ = { 651 | isa = PBXResourcesBuildPhase; 652 | buildActionMask = 2147483647; 653 | files = ( 654 | DFC63A541CC9115000500187 /* LaunchScreen.storyboard in Resources */, 655 | DFC63A511CC9115000500187 /* Assets.xcassets in Resources */, 656 | DFC63A4F1CC9115000500187 /* Main.storyboard in Resources */, 657 | ); 658 | runOnlyForDeploymentPostprocessing = 0; 659 | }; 660 | DFC63A5E1CC9159400500187 /* Resources */ = { 661 | isa = PBXResourcesBuildPhase; 662 | buildActionMask = 2147483647; 663 | files = ( 664 | DFC63A721CC9159400500187 /* LaunchScreen.storyboard in Resources */, 665 | DFC63A6F1CC9159400500187 /* Assets.xcassets in Resources */, 666 | DFC63A6D1CC9159400500187 /* Main.storyboard in Resources */, 667 | ); 668 | runOnlyForDeploymentPostprocessing = 0; 669 | }; 670 | /* End PBXResourcesBuildPhase section */ 671 | 672 | /* Begin PBXSourcesBuildPhase section */ 673 | DF1FFB051CCBC1D600E967B9 /* Sources */ = { 674 | isa = PBXSourcesBuildPhase; 675 | buildActionMask = 2147483647; 676 | files = ( 677 | DF1FFB221CCBC20900E967B9 /* Cat.m in Sources */, 678 | DF1FFB131CCBC1D600E967B9 /* ViewController.m in Sources */, 679 | DF1FFB101CCBC1D600E967B9 /* AppDelegate.m in Sources */, 680 | DF1FFB0D1CCBC1D600E967B9 /* main.m in Sources */, 681 | ); 682 | runOnlyForDeploymentPostprocessing = 0; 683 | }; 684 | DF1FFB231CCBE36800E967B9 /* Sources */ = { 685 | isa = PBXSourcesBuildPhase; 686 | buildActionMask = 2147483647; 687 | files = ( 688 | DF1FFB311CCBE36800E967B9 /* ViewController.m in Sources */, 689 | DF1FFB2E1CCBE36800E967B9 /* AppDelegate.m in Sources */, 690 | DF1FFB401CCBE38800E967B9 /* NSObject+Archive.m in Sources */, 691 | DF1FFB2B1CCBE36800E967B9 /* main.m in Sources */, 692 | DF1FFB431CCBE76700E967B9 /* Cat.m in Sources */, 693 | ); 694 | runOnlyForDeploymentPostprocessing = 0; 695 | }; 696 | DF6D03A21CCB6B9C006D70F0 /* Sources */ = { 697 | isa = PBXSourcesBuildPhase; 698 | buildActionMask = 2147483647; 699 | files = ( 700 | DF6D03B01CCB6B9C006D70F0 /* ViewController.m in Sources */, 701 | DF6D03BF1CCB6C18006D70F0 /* GithubUser.m in Sources */, 702 | DF6D03AD1CCB6B9C006D70F0 /* AppDelegate.m in Sources */, 703 | DF6D03AA1CCB6B9C006D70F0 /* main.m in Sources */, 704 | DF6D03C51CCBB931006D70F0 /* NSObject+Model.m in Sources */, 705 | ); 706 | runOnlyForDeploymentPostprocessing = 0; 707 | }; 708 | DFC63A021CC8FFF200500187 /* Sources */ = { 709 | isa = PBXSourcesBuildPhase; 710 | buildActionMask = 2147483647; 711 | files = ( 712 | DFC63A1F1CC900BE00500187 /* Cat.m in Sources */, 713 | DFC63A101CC8FFF200500187 /* ViewController.m in Sources */, 714 | DFC63A0D1CC8FFF200500187 /* AppDelegate.m in Sources */, 715 | DFC63A0A1CC8FFF200500187 /* main.m in Sources */, 716 | ); 717 | runOnlyForDeploymentPostprocessing = 0; 718 | }; 719 | DFC63A201CC90C9700500187 /* Sources */ = { 720 | isa = PBXSourcesBuildPhase; 721 | buildActionMask = 2147483647; 722 | files = ( 723 | DFC63A2E1CC90C9700500187 /* ViewController.m in Sources */, 724 | DFC63A3D1CC90DAD00500187 /* UIImage+Success.m in Sources */, 725 | DFC63A2B1CC90C9700500187 /* AppDelegate.m in Sources */, 726 | DFC63A281CC90C9700500187 /* main.m in Sources */, 727 | ); 728 | runOnlyForDeploymentPostprocessing = 0; 729 | }; 730 | DFC63A3E1CC9115000500187 /* Sources */ = { 731 | isa = PBXSourcesBuildPhase; 732 | buildActionMask = 2147483647; 733 | files = ( 734 | DFC63A5B1CC9118A00500187 /* Cat.m in Sources */, 735 | DFC63A4C1CC9115000500187 /* ViewController.m in Sources */, 736 | DFC63A491CC9115000500187 /* AppDelegate.m in Sources */, 737 | DFC63A461CC9115000500187 /* main.m in Sources */, 738 | ); 739 | runOnlyForDeploymentPostprocessing = 0; 740 | }; 741 | DFC63A5C1CC9159400500187 /* Sources */ = { 742 | isa = PBXSourcesBuildPhase; 743 | buildActionMask = 2147483647; 744 | files = ( 745 | DFC63A6A1CC9159400500187 /* ViewController.m in Sources */, 746 | DFC63A671CC9159400500187 /* AppDelegate.m in Sources */, 747 | DFC63A791CC9166A00500187 /* NSObject+Property.m in Sources */, 748 | DFC63A641CC9159400500187 /* main.m in Sources */, 749 | ); 750 | runOnlyForDeploymentPostprocessing = 0; 751 | }; 752 | /* End PBXSourcesBuildPhase section */ 753 | 754 | /* Begin PBXVariantGroup section */ 755 | DF1FFB141CCBC1D600E967B9 /* Main.storyboard */ = { 756 | isa = PBXVariantGroup; 757 | children = ( 758 | DF1FFB151CCBC1D600E967B9 /* Base */, 759 | ); 760 | name = Main.storyboard; 761 | sourceTree = ""; 762 | }; 763 | DF1FFB191CCBC1D600E967B9 /* LaunchScreen.storyboard */ = { 764 | isa = PBXVariantGroup; 765 | children = ( 766 | DF1FFB1A1CCBC1D600E967B9 /* Base */, 767 | ); 768 | name = LaunchScreen.storyboard; 769 | sourceTree = ""; 770 | }; 771 | DF1FFB321CCBE36800E967B9 /* Main.storyboard */ = { 772 | isa = PBXVariantGroup; 773 | children = ( 774 | DF1FFB331CCBE36800E967B9 /* Base */, 775 | ); 776 | name = Main.storyboard; 777 | sourceTree = ""; 778 | }; 779 | DF1FFB371CCBE36800E967B9 /* LaunchScreen.storyboard */ = { 780 | isa = PBXVariantGroup; 781 | children = ( 782 | DF1FFB381CCBE36800E967B9 /* Base */, 783 | ); 784 | name = LaunchScreen.storyboard; 785 | sourceTree = ""; 786 | }; 787 | DF6D03B11CCB6B9C006D70F0 /* Main.storyboard */ = { 788 | isa = PBXVariantGroup; 789 | children = ( 790 | DF6D03B21CCB6B9C006D70F0 /* Base */, 791 | ); 792 | name = Main.storyboard; 793 | sourceTree = ""; 794 | }; 795 | DF6D03B61CCB6B9C006D70F0 /* LaunchScreen.storyboard */ = { 796 | isa = PBXVariantGroup; 797 | children = ( 798 | DF6D03B71CCB6B9C006D70F0 /* Base */, 799 | ); 800 | name = LaunchScreen.storyboard; 801 | sourceTree = ""; 802 | }; 803 | DFC63A111CC8FFF200500187 /* Main.storyboard */ = { 804 | isa = PBXVariantGroup; 805 | children = ( 806 | DFC63A121CC8FFF200500187 /* Base */, 807 | ); 808 | name = Main.storyboard; 809 | sourceTree = ""; 810 | }; 811 | DFC63A161CC8FFF200500187 /* LaunchScreen.storyboard */ = { 812 | isa = PBXVariantGroup; 813 | children = ( 814 | DFC63A171CC8FFF200500187 /* Base */, 815 | ); 816 | name = LaunchScreen.storyboard; 817 | sourceTree = ""; 818 | }; 819 | DFC63A2F1CC90C9700500187 /* Main.storyboard */ = { 820 | isa = PBXVariantGroup; 821 | children = ( 822 | DFC63A301CC90C9700500187 /* Base */, 823 | ); 824 | name = Main.storyboard; 825 | sourceTree = ""; 826 | }; 827 | DFC63A341CC90C9700500187 /* LaunchScreen.storyboard */ = { 828 | isa = PBXVariantGroup; 829 | children = ( 830 | DFC63A351CC90C9700500187 /* Base */, 831 | ); 832 | name = LaunchScreen.storyboard; 833 | sourceTree = ""; 834 | }; 835 | DFC63A4D1CC9115000500187 /* Main.storyboard */ = { 836 | isa = PBXVariantGroup; 837 | children = ( 838 | DFC63A4E1CC9115000500187 /* Base */, 839 | ); 840 | name = Main.storyboard; 841 | sourceTree = ""; 842 | }; 843 | DFC63A521CC9115000500187 /* LaunchScreen.storyboard */ = { 844 | isa = PBXVariantGroup; 845 | children = ( 846 | DFC63A531CC9115000500187 /* Base */, 847 | ); 848 | name = LaunchScreen.storyboard; 849 | sourceTree = ""; 850 | }; 851 | DFC63A6B1CC9159400500187 /* Main.storyboard */ = { 852 | isa = PBXVariantGroup; 853 | children = ( 854 | DFC63A6C1CC9159400500187 /* Base */, 855 | ); 856 | name = Main.storyboard; 857 | sourceTree = ""; 858 | }; 859 | DFC63A701CC9159400500187 /* LaunchScreen.storyboard */ = { 860 | isa = PBXVariantGroup; 861 | children = ( 862 | DFC63A711CC9159400500187 /* Base */, 863 | ); 864 | name = LaunchScreen.storyboard; 865 | sourceTree = ""; 866 | }; 867 | /* End PBXVariantGroup section */ 868 | 869 | /* Begin XCBuildConfiguration section */ 870 | DF1FFB1D1CCBC1D600E967B9 /* Debug */ = { 871 | isa = XCBuildConfiguration; 872 | buildSettings = { 873 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 874 | INFOPLIST_FILE = ForwardMessage/Info.plist; 875 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 876 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.ForwardMessage; 877 | PRODUCT_NAME = "$(TARGET_NAME)"; 878 | }; 879 | name = Debug; 880 | }; 881 | DF1FFB1E1CCBC1D600E967B9 /* Release */ = { 882 | isa = XCBuildConfiguration; 883 | buildSettings = { 884 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 885 | INFOPLIST_FILE = ForwardMessage/Info.plist; 886 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 887 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.ForwardMessage; 888 | PRODUCT_NAME = "$(TARGET_NAME)"; 889 | }; 890 | name = Release; 891 | }; 892 | DF1FFB3C1CCBE36800E967B9 /* Debug */ = { 893 | isa = XCBuildConfiguration; 894 | buildSettings = { 895 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 896 | INFOPLIST_FILE = ObjectArchive/Info.plist; 897 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 898 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.ObjectArchive; 899 | PRODUCT_NAME = "$(TARGET_NAME)"; 900 | }; 901 | name = Debug; 902 | }; 903 | DF1FFB3D1CCBE36800E967B9 /* Release */ = { 904 | isa = XCBuildConfiguration; 905 | buildSettings = { 906 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 907 | INFOPLIST_FILE = ObjectArchive/Info.plist; 908 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 909 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.ObjectArchive; 910 | PRODUCT_NAME = "$(TARGET_NAME)"; 911 | }; 912 | name = Release; 913 | }; 914 | DF6D03BB1CCB6B9C006D70F0 /* Debug */ = { 915 | isa = XCBuildConfiguration; 916 | buildSettings = { 917 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 918 | INFOPLIST_FILE = MakeModel/Info.plist; 919 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 920 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.MakeModel; 921 | PRODUCT_NAME = "$(TARGET_NAME)"; 922 | }; 923 | name = Debug; 924 | }; 925 | DF6D03BC1CCB6B9C006D70F0 /* Release */ = { 926 | isa = XCBuildConfiguration; 927 | buildSettings = { 928 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 929 | INFOPLIST_FILE = MakeModel/Info.plist; 930 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 931 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.MakeModel; 932 | PRODUCT_NAME = "$(TARGET_NAME)"; 933 | }; 934 | name = Release; 935 | }; 936 | DFC639DF1CC8F2A100500187 /* Debug */ = { 937 | isa = XCBuildConfiguration; 938 | buildSettings = { 939 | ALWAYS_SEARCH_USER_PATHS = NO; 940 | CLANG_ANALYZER_NONNULL = YES; 941 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 942 | CLANG_CXX_LIBRARY = "libc++"; 943 | CLANG_ENABLE_MODULES = YES; 944 | CLANG_ENABLE_OBJC_ARC = YES; 945 | CLANG_WARN_BOOL_CONVERSION = YES; 946 | CLANG_WARN_CONSTANT_CONVERSION = YES; 947 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 948 | CLANG_WARN_EMPTY_BODY = YES; 949 | CLANG_WARN_ENUM_CONVERSION = YES; 950 | CLANG_WARN_INT_CONVERSION = YES; 951 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 952 | CLANG_WARN_UNREACHABLE_CODE = YES; 953 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 954 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 955 | COPY_PHASE_STRIP = NO; 956 | DEBUG_INFORMATION_FORMAT = dwarf; 957 | ENABLE_STRICT_OBJC_MSGSEND = YES; 958 | ENABLE_TESTABILITY = YES; 959 | GCC_C_LANGUAGE_STANDARD = gnu99; 960 | GCC_DYNAMIC_NO_PIC = NO; 961 | GCC_NO_COMMON_BLOCKS = YES; 962 | GCC_OPTIMIZATION_LEVEL = 0; 963 | GCC_PREPROCESSOR_DEFINITIONS = ( 964 | "DEBUG=1", 965 | "$(inherited)", 966 | ); 967 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 968 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 969 | GCC_WARN_UNDECLARED_SELECTOR = YES; 970 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 971 | GCC_WARN_UNUSED_FUNCTION = YES; 972 | GCC_WARN_UNUSED_VARIABLE = YES; 973 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 974 | MTL_ENABLE_DEBUG_INFO = YES; 975 | ONLY_ACTIVE_ARCH = YES; 976 | SDKROOT = iphoneos; 977 | TARGETED_DEVICE_FAMILY = "1,2"; 978 | }; 979 | name = Debug; 980 | }; 981 | DFC639E01CC8F2A100500187 /* Release */ = { 982 | isa = XCBuildConfiguration; 983 | buildSettings = { 984 | ALWAYS_SEARCH_USER_PATHS = NO; 985 | CLANG_ANALYZER_NONNULL = YES; 986 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 987 | CLANG_CXX_LIBRARY = "libc++"; 988 | CLANG_ENABLE_MODULES = YES; 989 | CLANG_ENABLE_OBJC_ARC = YES; 990 | CLANG_WARN_BOOL_CONVERSION = YES; 991 | CLANG_WARN_CONSTANT_CONVERSION = YES; 992 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 993 | CLANG_WARN_EMPTY_BODY = YES; 994 | CLANG_WARN_ENUM_CONVERSION = YES; 995 | CLANG_WARN_INT_CONVERSION = YES; 996 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 997 | CLANG_WARN_UNREACHABLE_CODE = YES; 998 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 999 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 1000 | COPY_PHASE_STRIP = NO; 1001 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1002 | ENABLE_NS_ASSERTIONS = NO; 1003 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1004 | GCC_C_LANGUAGE_STANDARD = gnu99; 1005 | GCC_NO_COMMON_BLOCKS = YES; 1006 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1007 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1008 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1009 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1010 | GCC_WARN_UNUSED_FUNCTION = YES; 1011 | GCC_WARN_UNUSED_VARIABLE = YES; 1012 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 1013 | MTL_ENABLE_DEBUG_INFO = NO; 1014 | SDKROOT = iphoneos; 1015 | TARGETED_DEVICE_FAMILY = "1,2"; 1016 | VALIDATE_PRODUCT = YES; 1017 | }; 1018 | name = Release; 1019 | }; 1020 | DFC63A1B1CC8FFF300500187 /* Debug */ = { 1021 | isa = XCBuildConfiguration; 1022 | buildSettings = { 1023 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1024 | ENABLE_STRICT_OBJC_MSGSEND = NO; 1025 | INFOPLIST_FILE = Messaging/Info.plist; 1026 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1027 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.Messaging; 1028 | PRODUCT_NAME = "$(TARGET_NAME)"; 1029 | }; 1030 | name = Debug; 1031 | }; 1032 | DFC63A1C1CC8FFF300500187 /* Release */ = { 1033 | isa = XCBuildConfiguration; 1034 | buildSettings = { 1035 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1036 | ENABLE_STRICT_OBJC_MSGSEND = NO; 1037 | INFOPLIST_FILE = Messaging/Info.plist; 1038 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1039 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.Messaging; 1040 | PRODUCT_NAME = "$(TARGET_NAME)"; 1041 | }; 1042 | name = Release; 1043 | }; 1044 | DFC63A391CC90C9700500187 /* Debug */ = { 1045 | isa = XCBuildConfiguration; 1046 | buildSettings = { 1047 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1048 | INFOPLIST_FILE = MethodSwizzling/Info.plist; 1049 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1050 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.MethodSwizzling; 1051 | PRODUCT_NAME = "$(TARGET_NAME)"; 1052 | }; 1053 | name = Debug; 1054 | }; 1055 | DFC63A3A1CC90C9700500187 /* Release */ = { 1056 | isa = XCBuildConfiguration; 1057 | buildSettings = { 1058 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1059 | INFOPLIST_FILE = MethodSwizzling/Info.plist; 1060 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1061 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.MethodSwizzling; 1062 | PRODUCT_NAME = "$(TARGET_NAME)"; 1063 | }; 1064 | name = Release; 1065 | }; 1066 | DFC63A571CC9115100500187 /* Debug */ = { 1067 | isa = XCBuildConfiguration; 1068 | buildSettings = { 1069 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1070 | INFOPLIST_FILE = ResolveInstanceMethod/Info.plist; 1071 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1072 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.ResolveInstanceMethod; 1073 | PRODUCT_NAME = "$(TARGET_NAME)"; 1074 | }; 1075 | name = Debug; 1076 | }; 1077 | DFC63A581CC9115100500187 /* Release */ = { 1078 | isa = XCBuildConfiguration; 1079 | buildSettings = { 1080 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1081 | INFOPLIST_FILE = ResolveInstanceMethod/Info.plist; 1082 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1083 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.ResolveInstanceMethod; 1084 | PRODUCT_NAME = "$(TARGET_NAME)"; 1085 | }; 1086 | name = Release; 1087 | }; 1088 | DFC63A751CC9159400500187 /* Debug */ = { 1089 | isa = XCBuildConfiguration; 1090 | buildSettings = { 1091 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1092 | INFOPLIST_FILE = AssociatedObject/Info.plist; 1093 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1094 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.AssociatedObject; 1095 | PRODUCT_NAME = "$(TARGET_NAME)"; 1096 | }; 1097 | name = Debug; 1098 | }; 1099 | DFC63A761CC9159400500187 /* Release */ = { 1100 | isa = XCBuildConfiguration; 1101 | buildSettings = { 1102 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1103 | INFOPLIST_FILE = AssociatedObject/Info.plist; 1104 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1105 | PRODUCT_BUNDLE_IDENTIFIER = com.tuccuay.AssociatedObject; 1106 | PRODUCT_NAME = "$(TARGET_NAME)"; 1107 | }; 1108 | name = Release; 1109 | }; 1110 | /* End XCBuildConfiguration section */ 1111 | 1112 | /* Begin XCConfigurationList section */ 1113 | DF1FFB1F1CCBC1D600E967B9 /* Build configuration list for PBXNativeTarget "ForwardMessage" */ = { 1114 | isa = XCConfigurationList; 1115 | buildConfigurations = ( 1116 | DF1FFB1D1CCBC1D600E967B9 /* Debug */, 1117 | DF1FFB1E1CCBC1D600E967B9 /* Release */, 1118 | ); 1119 | defaultConfigurationIsVisible = 0; 1120 | }; 1121 | DF1FFB3B1CCBE36800E967B9 /* Build configuration list for PBXNativeTarget "ObjectArchive" */ = { 1122 | isa = XCConfigurationList; 1123 | buildConfigurations = ( 1124 | DF1FFB3C1CCBE36800E967B9 /* Debug */, 1125 | DF1FFB3D1CCBE36800E967B9 /* Release */, 1126 | ); 1127 | defaultConfigurationIsVisible = 0; 1128 | }; 1129 | DF6D03BA1CCB6B9C006D70F0 /* Build configuration list for PBXNativeTarget "MakeModel" */ = { 1130 | isa = XCConfigurationList; 1131 | buildConfigurations = ( 1132 | DF6D03BB1CCB6B9C006D70F0 /* Debug */, 1133 | DF6D03BC1CCB6B9C006D70F0 /* Release */, 1134 | ); 1135 | defaultConfigurationIsVisible = 0; 1136 | defaultConfigurationName = Release; 1137 | }; 1138 | DFC639C51CC8F2A000500187 /* Build configuration list for PBXProject "RuntimeSummary" */ = { 1139 | isa = XCConfigurationList; 1140 | buildConfigurations = ( 1141 | DFC639DF1CC8F2A100500187 /* Debug */, 1142 | DFC639E01CC8F2A100500187 /* Release */, 1143 | ); 1144 | defaultConfigurationIsVisible = 0; 1145 | defaultConfigurationName = Release; 1146 | }; 1147 | DFC63A1A1CC8FFF300500187 /* Build configuration list for PBXNativeTarget "Messaging" */ = { 1148 | isa = XCConfigurationList; 1149 | buildConfigurations = ( 1150 | DFC63A1B1CC8FFF300500187 /* Debug */, 1151 | DFC63A1C1CC8FFF300500187 /* Release */, 1152 | ); 1153 | defaultConfigurationIsVisible = 0; 1154 | defaultConfigurationName = Release; 1155 | }; 1156 | DFC63A381CC90C9700500187 /* Build configuration list for PBXNativeTarget "MethodSwizzling" */ = { 1157 | isa = XCConfigurationList; 1158 | buildConfigurations = ( 1159 | DFC63A391CC90C9700500187 /* Debug */, 1160 | DFC63A3A1CC90C9700500187 /* Release */, 1161 | ); 1162 | defaultConfigurationIsVisible = 0; 1163 | defaultConfigurationName = Release; 1164 | }; 1165 | DFC63A561CC9115100500187 /* Build configuration list for PBXNativeTarget "ResolveInstanceMethod" */ = { 1166 | isa = XCConfigurationList; 1167 | buildConfigurations = ( 1168 | DFC63A571CC9115100500187 /* Debug */, 1169 | DFC63A581CC9115100500187 /* Release */, 1170 | ); 1171 | defaultConfigurationIsVisible = 0; 1172 | defaultConfigurationName = Release; 1173 | }; 1174 | DFC63A741CC9159400500187 /* Build configuration list for PBXNativeTarget "AssociatedObject" */ = { 1175 | isa = XCConfigurationList; 1176 | buildConfigurations = ( 1177 | DFC63A751CC9159400500187 /* Debug */, 1178 | DFC63A761CC9159400500187 /* Release */, 1179 | ); 1180 | defaultConfigurationIsVisible = 0; 1181 | defaultConfigurationName = Release; 1182 | }; 1183 | /* End XCConfigurationList section */ 1184 | }; 1185 | rootObject = DFC639C21CC8F2A000500187 /* Project object */; 1186 | } 1187 | -------------------------------------------------------------------------------- /RuntimeSummary.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | --------------------------------------------------------------------------------