実行時
14981 ワード
1.メッセージメカニズム
2.交換方法
3.動的追加方法
4.分類追加属性
5.辞書回転モデルKVC実現
6.ランタイム辞書回転モデル
#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