|
iOS培訓(xùn)通過runtime獲取類屬性和類方法
// NSObject+DateBaseModel.h
// LightApp
//
// Created by malong on 14/11/15.
// Copyright (c) 2014年 malong. All rights reserved.
//
/*
runtime是什么:運行時刻是指一個程序在運行(或者在被執(zhí)行)的狀態(tài)。
Runtime類封裝了運行時的環(huán)境。它屬于C語言庫, 有很多底層的C語言API。
要點:1、不能實例化一個Runtime對象
2、可以通過 getRuntime 方法獲取當(dāng)前Runtime運行時對象的引用
runtime可以干什么?
runtime是屬于OC的底層, 可以進(jìn)行一些非常底層的操作(用OC是無法現(xiàn)實的, 不好實現(xiàn))
在程序運行過程中, 動態(tài)創(chuàng)建一個類(比如KVO的底層實現(xiàn))、動態(tài)地為某個類添加屬性\方法, 修改屬性值\方法
遍歷一個類的所有成員變量(屬性)\所有方法
典型例子:KVO的底層實現(xiàn)
*/
#import <Foundation/Foundation.h>
/**
* @brief 數(shù)據(jù)庫模型類目
*/
@interface NSObject (DateBaseModel)
/**
* @brief 屬性列表
*/
- (NSDictionary *)propertiesDic;
/**
* @brief 屬性列表名數(shù)組
*/
- (NSMutableArray*)propertyNames;
/**
* @brief 屬性對應(yīng)值數(shù)組
*/
- (NSMutableArray*)propertyVaules;
/**
* @brief 獲取對象的所有方法信息
*/
-(NSArray *)mothodLists;
- (void) setFlashColor:(UIColor *) flashColor;
- (UIColor *) getFlashColor;
@end
[/mw_shl_code]
[mw_shl_code=objc,true]//
// NSObject+DateBaseModel.m
// LightApp
//
// Created by malong on 14/11/15.
// Copyright (c) 2014年 malong. All rights reserved.
//
#import "NSObject+DateBaseModel.h"
#import <objc/runtime.h>
@implementation NSObject (DateBaseModel)
- (NSDictionary *)propertiesDic {
NSMutableDictionary *props =
[NSMutableDictionary dictionary];
unsigned int outCount, i;
objc_property_t * properties =
class_copyPropertyList([self class], &outCount);
for (i = 0; i < outCount; i++)
{
objc_property_t property = properties;
NSString *propertyName = [[NSString
alloc] initWithCString:property_getName(property)
encoding:NSUTF8StringEncoding];
id propertyValue = [self valueForKey:(NSString
*)propertyName];
if (propertyValue) [props
setObject:propertyValue forKey:propertyName];
}
free(properties);
return props;
// return [self dictionaryWithValuesForKeys:[self propertyNames]];
}
- (NSMutableArray*)propertyNames{
unsigned int outCount, i;
objc_property_t * properties = class_copyPropertyList([self
class], &outCount);
NSMutableArray * propertyNames = [NSMutableArray
arrayWithCapacity:outCount];
for (i = 0; i < outCount; i++) {
objc_property_t property = properties;
NSString *propertyName = [[NSString
alloc] initWithCString:property_getName(property)
encoding:NSUTF8StringEncoding];
[propertyNames addObject:propertyName];
}
free(properties);
return propertyNames;
}
- (NSMutableArray *)propertyVaules{
NSMutableArray * propertyNames = [self propertyNames];
NSMutableArray * propertyVaules = [NSMutableArray
arrayWithCapacity:propertyNames.count];
for (int i = 0; i<propertyNames.count; i++) {
id propertyValue = [self
valueForKey:[propertyNames objectAtIndex:i]];
if (nil != propertyValue) {
[propertyVaules
addObject:propertyValue];
}
}
return propertyVaules;
// return [[self propertiesDic] allValues];
}
/**
* @brief 獲取對象的所有方法信息
*/
-(NSArray *)mothodLists
{
unsigned int mothCout =0;
//獲取方法列表
Method* methodList = class_copyMethodList([self class],&mothCout);
//創(chuàng)建存儲方法信息的數(shù)組
NSMutableArray * methodlists = [NSMutableArray array];
//遍歷數(shù)組,提取每個方法的信息
for(int i=0;i<mothCout;i++)
{
//獲取方法
Method method = methodList;
// IMP imp_f =
method_getImplementation(temp_f);
// SEL name_f = method_getName(temp_f);
//創(chuàng)建方法信息字典
NSMutableDictionary * methodInfo =
[NSMutableDictionary dictionary];
//獲取方法名
const char * name
=sel_getName(method_getName(method));
NSString * methodName = [NSString
stringWithUTF8String:name];
[methodInfo setValue:methodName
forKey:@"methodName"];
//獲取方法返回值類型
const char * returnType =
method_copyReturnType(method);
NSString * returnTypeString = [NSString
stringWithUTF8String:returnType];
[methodInfo setValue:returnTypeString
forKey:@"returnTypeString"];
//獲取方法參數(shù)個數(shù)、每個參數(shù)的類型
int arguments =
method_getNumberOfArguments(method);
if (arguments) {
//創(chuàng)建存儲參數(shù)類型名的數(shù)組
NSMutableArray *
methodArgumentTypes = [NSMutableArray array];
for (int j = 0;
j<arguments; j++) {
//獲取每個參數(shù)的類型
char
argumentType[256];
method_getArgumentType(method, j, argumentType, 256);
NSString *
argumentTypeName = [NSString stringWithUTF8String:argumentType];
[methodArgumentTypes addObject:argumentTypeName];
}
[methodInfo
setObject:methodArgumentTypes forKey:@"methodArgumentTypes"];
}
//獲取方法編碼格式
const char* encoding =
method_getTypeEncoding(method);
NSString * encodingName = [NSString stringWithUTF8String:encoding];
[methodInfo setValue:encodingName
forKey:@"encodingName"];
DLog(@"方法名:%@,參數(shù)個數(shù):%d,編碼方式:%@",methodName,
arguments,
[NSString
stringWithUTF8String:encoding]);
[methodlists addObject:methodInfo];
}
free(methodList);
return methodlists;
}
static char flashColorKey;
- (void) setFlashColor:(UIColor *) flashColor{
objc_setAssociatedObject(self, &flashColorKey, flashColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIColor *) getFlashColor{
return objc_getAssociatedObject(self, &flashColorKey);
}
@end
|