#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end #import "ViewController.h" #import <objc/runtime.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //動態建立對象 //建立一個名爲DemoCustomView的類 它是UIView的子類 Class newClass = objc_allocateClassPair([UIView class], "DemoCustomView", 0); //爲該類增長一個名爲report的方法 class_addMethod(newClass, @selector(report), (IMP)ReportFunction, "v@:"); //註冊該類 objc_registerClassPair(newClass); //建立一個DemoCustomView類的實例 id instanceOfNewClass = [[newClass alloc]init]; //調用report方法 [instanceOfNewClass performSelector:@selector(report)]; } void ReportFunction(id self,SEL _cmd){ NSLog(@"This object is %p",self); NSLog(@"Class is %@,and super is %@",[self class],[self superclass]); Class currentClass = [self class]; for (int i = 1;i<5;i++){ NSLog(@"Following the isa pointer %d times gives %p",i,currentClass); currentClass = object_getClass(currentClass);//得到對象的isa指針所指向的對象 } NSLog(@"NSObject's class is %p",[NSObject class]); NSLog(@"NSObject's meta class is %p",object_getClass([NSObject class])); /* 2016-04-27 14:43:59.683 OC對象模型[11609:1157519] This object is 0x7fd208c2fe10 2016-04-27 14:43:59.684 OC對象模型[11609:1157519] Class is DemoCustomView,and super is UIView 2016-04-27 14:43:59.684 OC對象模型[11609:1157519] Following the isa pointer 1 times gives 0x7fd208c19080 2016-04-27 14:43:59.684 OC對象模型[11609:1157519] Following the isa pointer 2 times gives 0x7fd208c32c70 2016-04-27 14:43:59.684 OC對象模型[11609:1157519] Following the isa pointer 3 times gives 0x1008f6198 2016-04-27 14:43:59.684 OC對象模型[11609:1157519] Following the isa pointer 4 times gives 0x1008f6198 2016-04-27 14:43:59.684 OC對象模型[11609:1157519] NSObject's class is 0x1008f6170 2016-04-27 14:43:59.684 OC對象模型[11609:1157519] NSObject's meta class is 0x1008f6198 */ } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface ImagePickerReplaceMethodsHolder : NSObject -(BOOL)shouldAutorotate; -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation; @end #import "ImagePickerReplaceMethodsHolder.h" @implementation ImagePickerReplaceMethodsHolder -(BOOL)shouldAutorotate{ return NO; } -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ return UIInterfaceOrientationPortrait; } @end
#import <UIKit/UIKit.h> @interface ImagePickerViewDemo : UIImagePickerController @end #import "ImagePickerViewDemo.h" #import "ImagePickerReplaceMethodsHolder.h" #import <objc/runtime.h> #define SYSTEM_VERSION_CREATE_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion]compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion]compare:v options:NSNumericSearch] == NSOrderedAscending) @implementation ImagePickerViewDemo -(void)load{ static dispatch_once_t onceToken; dispatch_once(&onceToken,^{ [self hackForImagePicker]; }); } -(void)hackForImagePicker{ //iOS swizzling的應用 //動態替換類方法或實例方法 //API //1. class_replaceMethod 替換類方法的定義 //2. method_exchangeImplementations 交換兩個方法的實現 //3. method_setImplementation 設置一個方法的實現 if (SYSTEM_VERSION_CREATE_THAN_OR_EQUAL_TO(@"6.0") && SYSTEM_VERSION_LESS_THAN(@"6.1")){ Method oldMethod1 = class_getInstanceMethod([UIImagePickerController class], @selector(shouldAutorotate)); Method newMethod1 = class_getInstanceMethod([ImagePickerReplaceMethodsHolder class], @selector(shouldAutorotate)); method_setImplementation(oldMethod1, method_getImplementation(newMethod1)); Method oldMethod2 = class_getInstanceMethod([UIImagePickerController class], @selector(preferredInterfaceOrientationForPresentation)); Method newMethod2 = class_getInstanceMethod([ImagePickerReplaceMethodsHolder class], @selector(preferredInterfaceOrientationForPresentation)); method_setImplementation(oldMethod2, method_getImplementation(newMethod2)); } } @end
#import <Foundation/Foundation.h> @interface Father : NSObject @end #import "Father.h" @implementation Father { int _father; } @end
#import "Father.h" @interface Son : Father @end #import "Son.h" @implementation Son { int _son; } @end
#import <UIKit/UIKit.h> #import "AppDelegate.h" #import "Son.h" int main(int argc, char * argv[]) { Son *son = [[Son alloc]init]; /* 控制檯打印 (lldb) p *son (Son) $2 = { Father = { NSObject = { isa = Son } _father = 0 } _son = 0 } */ @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }