実行時

14981 ワード

1.メッセージメカニズム
#import "ViewController.h"

#import "Person.h"


//          :  
//    :Build Setting ->   msg ->      No
#import 

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    Person *p = [[Person alloc] init];
    
    //    
//    [p eat];
    // OC:     ,                
    //     :      ,        
    
    // SEL:    ,                 
//    [p performSelector:@selector(eat)];
    
    //    ,    ,       
    // xcode5  ,           
    // xcode5  ,     .
    
    //  p    
    objc_msgSend(p, @selector(eat));
    objc_msgSend(p, @selector(run:),10);
    
    //        ,          
//    [Person eat];
    
    //      
    Class personClass = [Person class];
    
//    [personClass performSelector:@selector(eat)];
    
    //    
    objc_msgSend(personClass, @selector(eat));
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


2.交換方法
#import "ViewController.h"

//#import "UIImage+Image.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
//    UIImage *image = [UIImage imageNamed:@"123"];
    // 1.    ,        
    // 2.         ,         
    [UIImage imageNamed:@"123"];
    
    // imageNamed:
    //     :    xmg_imageNamed
    
    //   :         imageNamed xmg_imageNamed  
    //   imageNamed      xmg_imageNamed
    
    
    // imageNamed    ,            
    //     imageNamed   ,         
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


#import "UIImage+Image.h"

#import 

@implementation UIImage (Image)
//            
+ (void)load
{

    //       ,          
    // class_getMethodImplementation:      
    // class_getInstanceMethod:    
    // class_getClassMethod:     
    // IMP:    
    
    // imageNamed
    // Class:       
    // SEL:      ,  SEL          
    Method imageNameMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
    
    // xmg_imageNamed
    Method xmg_imageNamedMethod = class_getClassMethod([UIImage class], @selector(xmg_imageNamed:));
    
    //       
    method_exchangeImplementations(imageNameMethod, xmg_imageNamedMethod);
    
}

//    

//         ,      

//          super,      
//+ (UIImage *)imageNamed:(NSString *)name
//{
//    [super im]
//}

+ (UIImage *)xmg_imageNamed:(NSString *)imageName
{
    // 1.    
    UIImage *image = [UIImage xmg_imageNamed:imageName];
    
    // 2.    
    if (image == nil) {
        NSLog(@"  image  ");
    }
    
    return image;
}

@end


3.動的追加方法
#import 

@interface Person : NSObject

@end

#import "Person.h"

#import 

@implementation Person

//     
//      ,  (id,SEL)
// void(id,SEL)
void aaaa(id self, SEL _cmd, id param1)
{
    
    NSLog(@"  eat %@ %@ %@",self,NSStringFromSelector(_cmd),param1);
}

//             ,self,_cmd,    
// self:     
// _cmd:       

//       ,      resolveInstanceMethod
// resolveInstanceMethod  :                   resolveInstanceMethod
// resolveInstanceMethod  :           ,        
// sel:      


+ (BOOL)resolveInstanceMethod:(SEL)sel
{
//    NSLog(@"%@",NSStringFromSelector(sel));
    
    //     eat  
    
    if (sel == @selector(eat:)) {
        
        /*
         cls:        
         SEL:            
         IMP:    ,    ,   
         types:    
         */
        // @:   :SEL
        class_addMethod(self, sel, (IMP)aaaa, "v@:@");
        
        
        //    
        return YES;
        
    }
    
    
    return [super resolveInstanceMethod:sel];
}
@end

#import "ViewController.h"

#import "Person.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // performSelector:      
    Person *p = [[Person alloc] init];
    
    //       
//    [p performSelector:@selector(eat)];
    [p performSelector:@selector(eat:) withObject:@111];
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


4.分類追加属性
#import 


@interface NSObject (Objc)

@property (nonatomic, strong) NSString *name;

@end

#import "NSObject+Objc.h"

#import 

@implementation NSObject (Objc)

//static NSString *_name;



- (void)setName:(NSString *)name
{
    //     ,   
    //          ,    
    // object:         
    // key:   ,  key         ,void * == id
    // value:    
    // policy:  
    objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//    _name = name;
}

- (NSString *)name
{
    return objc_getAssociatedObject(self, @"name");
}

@end

#import "ViewController.h"

#import "NSObject+Objc.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSObject *objc = [[NSObject alloc] init];
    objc.name = @"123";
    NSLog(@"%@",objc.name);
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


5.辞書回転モデルKVC実現
#import 

@interface Status : NSObject

//              
@property (nonatomic, assign) NSInteger ID;
//             
@property (nonatomic, strong) NSString *source;

@property (nonatomic, assign) int reposts_count;

@property (nonatomic, strong) NSArray *pic_urls;

@property (nonatomic, strong) NSString *created_at;

@property (nonatomic, assign) int attitudes_count;

@property (nonatomic, strong) NSString *idstr;

@property (nonatomic, strong) NSString *text;

@property (nonatomic, assign) int comments_count;

@property (nonatomic, strong) NSDictionary *user;
//              

+ (__kindof Status *)statusWithDict:(NSDictionary *)dict;
@end

#import "Status.h"

@implementation Status
+ (Status *)statusWithDict:(NSDictionary *)dict
{
    Status *status = [[self alloc] init];
    
    // KVC
    [status setValuesForKeysWithDictionary:dict];
    
    return status;
}

//   KVC  
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    if ([key isEqualToString:@"id"]) {
        _ID = [value integerValue];
    }
    // key:    key
    // value:    key    
    NSLog(@"%@ %@",key,value);
}


@end

#import 

@interface NSObject (Property)

+ (void)createPropertyCodeWithDict:(NSDictionary *)dict;


@end
#import "NSObject+Property.h"

@implementation NSObject (Property)

+ (void)createPropertyCodeWithDict:(NSDictionary *)dict
{
    
    NSMutableString *strM = [NSMutableString string];

    //     
    [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull propertyName, id  _Nonnull value, BOOL * _Nonnull stop) {
        //        NSLog(@"%@ %@",propertyName,[value class]);
        NSString *code;

        if ([value isKindOfClass:NSClassFromString(@"__NSCFString")]) {
            code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSString *%@;",propertyName]
            ;
        }else if ([value isKindOfClass:NSClassFromString(@"__NSCFNumber")]){
            code = [NSString stringWithFormat:@"@property (nonatomic, assign) int %@;",propertyName]
            ;
        }else if ([value isKindOfClass:NSClassFromString(@"__NSCFArray")]){
            code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSArray *%@;",propertyName]
            ;
        }else if ([value isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){
            code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSDictionary *%@;",propertyName]
            ;
        }else if ([value isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){
            code = [NSString stringWithFormat:@"@property (nonatomic, assign) BOOL %@;",propertyName]
            ;
        }
        [strM appendFormat:@"
%@
",code]; }]; NSLog(@"%@",strM); } @end #import "ViewController.h" #import "NSObject+Property.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // Plist NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil]; NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath]; NSArray *dictArr = dict[@"statuses"]; // [NSObject createPropertyCodeWithDict:dictArr[0][@"user"]]; for (NSDictionary *dict in dictArr) { // } NSMutableArray *statuses = [NSMutableArray array]; for (NSDictionary *dict in dictArr) { // Status *status = [Status statusWithDict:dict]; [statuses addObject:status]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end

6.ランタイム辞書回転モデル
#import 

@interface User : NSObject

@property (nonatomic, strong) NSString *profile_image_url;

@property (nonatomic, assign) BOOL vip;

@property (nonatomic, strong) NSString *name;

@property (nonatomic, assign) int mbrank;

@property (nonatomic, assign) int mbtype;

@end
#import "User.h"

@implementation User

@end

#import 
@class User;
@interface Status : NSObject

//              

@property (nonatomic, assign) NSInteger ID;
//             
@property (nonatomic, strong) NSString *source;

@property (nonatomic, assign) NSInteger reposts_count;

@property (nonatomic, strong) NSArray *pic_urls;

@property (nonatomic, strong) NSString *created_at;

@property (nonatomic, assign) int attitudes_count;

@property (nonatomic, strong) NSString *idstr;

@property (nonatomic, strong) NSString *text;

@property (nonatomic, assign) int comments_count;

@property (nonatomic, strong) User *user;

@property (nonatomic, strong) NSDictionary *retweeted_status;

//              

+ (__kindof Status *)statusWithDict:(NSDictionary *)dict;

@end
#import "Status.h"

@implementation Status


+ (Status *)statusWithDict:(NSDictionary *)dict
{
    Status *status = [[self alloc] init];
    
    // KVC
    [status setValuesForKeysWithDictionary:dict];
    
    return status;
}

//   KVC  
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    if ([key isEqualToString:@"id"]) {
        _ID = [value integerValue];
    }
    // key:    key
    // value:    key    
    NSLog(@"%@ %@",key,value);
}

@end

#import 

@interface NSObject (Model)

+ (instancetype)modelWithDict:(NSDictionary *)dict;

@end

#import "NSObject+Model.h"

#import 
/*
 Ivar ivar1;
 Ivar ivar2;
 Ivar ivar3;
 Ivar a[] = {ivar3,ivar1,ivar2};
 Ivar *ivar = &a;

 */
@implementation NSObject (Model)
+ (instancetype)modelWithDict:(NSDictionary *)dict{
    
    // 1.        
    id objc = [[self alloc] init];
    
    // runtime:           ,      
    //       ,    ,         (  )
    
    //           
    // ivar:    
    // class_copyIvarList:             
    // Ivar *:  Ivar  
    // Ivar *:          
    // class:            
    // count:      
    unsigned int count = 0;
    Ivar *ivarList = class_copyIvarList(self, &count);
    for (int i = 0 ; i < count; i++) {
        //       
        Ivar ivar = ivarList[i];
        
        //      
       NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)];
        ;
        

        //   key
        NSString *key = [propertyName substringFromIndex:1];
        
        // user value:  
        //      value
        id value = dict[key];
        //         
        // value:    
        // key:   
        
        //       
        NSString *propertyType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        // user:NSDictionary
        //     
        //     ,           ,        
        if ([value isKindOfClass:[NSDictionary class]] && ![propertyType containsString:@"NS"]) { //          
            //        
            
            // @"@\"User\"" User
            NSRange range = [propertyType rangeOfString:@"\""];
            propertyType = [propertyType substringFromIndex:range.location + range.length];
            // User\"";
            range = [propertyType rangeOfString:@"\""];
            propertyType = [propertyType substringToIndex:range.location];
            
            //      
            
            //            
        
           Class modelClass =  NSClassFromString(propertyType);
        
            if (modelClass) {
                value =  [modelClass modelWithDict:value];
                
            }
        }
        
        if (value) {
            // KVC  :    
            [objc setValue:value forKey:key];
            
        }

    }
    
    
    return objc;
}
@end

#import "ViewController.h"
#import "Status.h"

#import "NSObject+Model.h"
@interface ViewController ()

@end

@implementation ViewController

/*
    KVC:       key,               
    runtime:          ,      
 */

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //   Plist
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil];
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
    NSArray *dictArr = dict[@"statuses"];
    
    NSMutableArray *statuses = [NSMutableArray array];
    //       
    for (NSDictionary *dict in dictArr) {
        Status *status = [Status modelWithDict:dict];
        [statuses addObject:status];
    }
    
    NSLog(@"%@",statuses);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end