iOS Runtime 学习笔记

  • 简单了解一下 Runtime (大神请直接飘过)

首先先从最常用的把遍历@property开始(转载)

unsigned int propsCount, i;
objc_property_t *props = class_copyPropertyList([ssc class], &propsCount);
for (i = 0; i < propsCount; i++) {
    objc_property_t prop = props[i];
    const char * propName = property_getName(prop);
    id value = [ssc valueForKey:[NSString stringWithUTF8String:propName]];
    GLog(value);
}

接下来说说用处: 在ios数据解析中,我们可以把数据结构以数据模型model的形式存储,这时候,比起用字典、数据模型有很大的优势,那么我们就可以用这种方法来判断类中是否有相应的属性与节点名字相同,我们就可以做出相应的存储了。数据解析方法在这里就省略了。。。


好的,下面开始runtime 的基础学习

TextFirst *first = [[TextFirst alloc]init];
    
    const char *className = class_getName([TextFirst class]);
    //获取类名 同NSStringFromClass();
    NSLog(@"className: %@",[NSString stringWithUTF8String:className]);
    
    const char *superClassName = class_getName(class_getSuperclass([TextFirst class]));
    //获取父类
    NSLog(@"superClass: %@",[NSString stringWithUTF8String:superClassName]);
    
    objc_property_t property_t = class_getProperty([TextFirst class], "name");
    const char *property_name = property_getName(property_t);
    NSLog(@"property_name: %s",property_name);
    
    const char *attributes = property_getAttributes(property_t);
    NSLog(@"attributes: %s",attributes);
    //获取类中属性的属性。。。(翻译的不好)打印就是:T@"NSString",&,N,Vname
    const char *value = property_copyAttributeValue(property_t, "T");
    NSLog(@"value: %s",value);//NSString
    
    unsigned int count1;
    objc_property_attribute_t *attribute_t = property_copyAttributeList(property_t, &count1);
    NSLog(@"count1: %d, name : %s, value: %s",count1, attribute_t ->name,attribute_t->value);
    //获取property 的属性,一共有四个,打印出name 和 value --- count1: 4, name : T, value: @"NSString"
    
    unsigned int count;
    objc_property_t *property_t_array = class_copyPropertyList([TextFirst class], &count);
    //获取属性的数组
    for (int i = 0 ; i < count; i++) {
        objc_property_t pro_t = property_t_array[i];
        const char *pro_name = property_getName(pro_t);
        id value = [first valueForKey:[NSString stringWithUTF8String:pro_name]];
        //根据键获取值
    }
    
    class_setVersion([TextFirst class], 1);
    //设置类的version 不是太懂意思,官方文档大概意思是:你可以用类的版本号控制与其他类的交互,尤其是用在objective-c 序列化中
    //英文原文:
    //You can use the version number of the class definition to provide versioning of the interface that your class represents to other classes. This is especially useful for object serialization (that is, archiving of the object in a flattened form), where it is important to recognize changes to the layout of the instance variables in different class-definition versions
    
    int version = class_getVersion([TextFirst class]);
    //获取版本信息吗???( 不只有何作用 返回0 )
    NSLog(@"version: %d",version);
    
    const char *weaklvarLayout = class_getWeakIvarLayout([TextFirst class]);//真心不知道干嘛的,求大神指点
    NSLog(@"layout : %s",weaklvarLayout);
    
    BOOL isMeta = class_isMetaClass([TextFirst class]);
    //判断一个类是不是元类,在我转载的另一篇博客中有讲解元类的,其实不不太懂
    NSLog(@"%d",isMeta);
    
    BOOL success = class_respondsToSelector([TextFirst class], @selector(action:));
    //佟respondsToSelector 方法
    NSLog(@"%d",success);
    
    id class = objc_getClass("TextFirst");
    //根据字符串获取类名
    if (class_respondsToSelector(class, @selector(action:))) {
        NSLog(@"class is TextFirst");
    }
    
    Protocol *protocol = objc_getProtocol("TextFieldDelegate");
    //只能识别出本类已经签订了的协议,其他类和本类自己的protocol 不能识别
    if (protocol) {
        NSLog(@"protocolName : %s",protocol_getName(protocol));
    }

打印结果:

2013-10-26 14:02:57.912 Runtime_Reference_Study[57553:a0b] className: TextFirst
2013-10-26 14:02:57.912 Runtime_Reference_Study[57553:a0b] superClass: NSObject
2013-10-26 14:02:57.912 Runtime_Reference_Study[57553:a0b] property_name: name
2013-10-26 14:02:57.913 Runtime_Reference_Study[57553:a0b] attributes: T@"NSString",&,N,Vname
2013-10-26 14:02:57.913 Runtime_Reference_Study[57553:a0b] value: (null)
2013-10-26 14:02:57.913 Runtime_Reference_Study[57553:a0b] count1: 4, name : T, value: @"NSString"
2013-10-26 14:02:57.914 Runtime_Reference_Study[57553:a0b] version: 1
2013-10-26 14:02:57.914 Runtime_Reference_Study[57553:a0b] layout : (null)
2013-10-26 14:02:57.914 Runtime_Reference_Study[57553:a0b] 0
2013-10-26 14:02:57.915 Runtime_Reference_Study[57553:a0b] 1
2013-10-26 14:02:57.915 Runtime_Reference_Study[57553:a0b] class is TextFirst
2013-10-26 14:02:57.916 Runtime_Reference_Study[57553:a0b] protocolName : TextFieldDelegate


下面这个方法是用来复制对象的,包括对象中各个属性的值,即使属性中有自定义对象类型的也可以复制:

- (id)copyItem:(id)item{
    //首先创建出一个对象
    id newItem = [[[item class] alloc]init];
    //获取属性的列表
    unsigned int count;
    objc_property_t *property_t_array = class_copyPropertyList([item class], &count);
    for (int i = 0 ; i < count ; i ++) {
        objc_property_t pro_t = property_t_array[i];//获取对象的某个属性
        const char *pro_name = property_getName(pro_t);//得到属性名字的字符串
        id value = [item valueForKey:[NSString stringWithUTF8String:pro_name]];//得到对应的值
        NSString *key = [NSString stringWithUTF8String:pro_name];
        [newItem setValue:value forKey:key];
    }
    free(property_t_array);
    return newItem;
}



如下方法用来获取属性的类型

/**
 根据objc_property_t 获取 property 的 type
 */
static const char* getPropertyType(objc_property_t property) {
	
    const char *attributes = property_getAttributes(property);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
	
    char *state = buffer;
	char *attribute;
	while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T' && strlen(attribute)>2) {
            
            static char newbuffer[100];
            memset(newbuffer, 0x00, 100);
            strncpy(newbuffer, (attribute + 3), strlen(attribute)-4);
            newbuffer[1 + strlen(attribute)-4] = '\n';
            
            return newbuffer;
            
			
        }else if (attribute[0] == 'T' && strlen(attribute)==2) {
            static char newbuffer[100];
            memset(newbuffer, 0x00, 100);
            strncpy(newbuffer, (attribute + 1), strlen(attribute)-1);
            newbuffer[strlen(attribute)-1] = '\n';
			return newbuffer;
		}
    }
	
    return "@";
	
}

附件地址: http://download.csdn.net/detail/u010889390/6850389

暂时也就理解这么多,可能有理解错误的地方!



你可能感兴趣的:(Objective-C,Runtime)