runtime跳转界面以及动态添加属性

来源:互联网 发布:俊知集团有救吗 编辑:程序博客网 时间:2024/04/27 08:12
////  ViewController.m//  Runtime处理界面跳转////  Created by 陆巧怡 on 15/9/15.//  Copyright (c) 2015年 Simon. All rights reserved.//#import "ViewController.h"#import <objc/runtime.h>@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor whiteColor];    for (int i = 0; i<5; i++) {                UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];        btn.frame = CGRectMake(0, 20+50*(i+1), 100, 40);        [btn setTitle:[NSString stringWithFormat:@"第%d个界面",i+1] forState:UIControlStateNormal];        btn.tag = i+1;        [btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];        [self.view addSubview:btn];    }}-(void)btnAction:(UIButton *)btn{        NSString *viewcontrollerName = nil;        switch (btn.tag) {        case 1:        {            viewcontrollerName = @"FirstViewController";        }            break;        case 2:        {            viewcontrollerName = @"SecondViewController";        }            break;        case 3:        {            viewcontrollerName = @"ThreeViewController";        }            break;        case 4:        {            viewcontrollerName = @"FourViewController";        }            break;        case 5:        {            viewcontrollerName = @"FiveViewController";        }            break;        default:            break;    }            [self pushViewcontroller:viewcontrollerName];}-(void)pushViewcontroller:(NSString *)viewcontrollerName{                //类名转换成char字符,用于下面创建类    const char *className = [viewcontrollerName cStringUsingEncoding:NSASCIIStringEncoding];    //获取目标类    Class targetObject = objc_getClass(className);        //如果这个类不存在===>动态创建类    if (!targetObject) {        /*         运行时创建类只需要三步:         1、为"class pair"分配空间(使用objc_allocateClassPair).         2、为创建的类添加方法和成员(上例使用class_addMethod添加了一个方法)。         3、注册你创建的这个类,使其可用(使用objc_registerClassPair)。         */        //创建一个类        Class newClass = [NSObject class];        targetObject = objc_allocateClassPair(newClass, className, 0);        //注册这个类        objc_registerClassPair(targetObject);            }        //创建对象    id instanceObject = [[targetObject alloc]init];        /*        在这里,除了FirstViewController才有一个titleName的属性,其他ViewController都没有        模拟动态增加属性以及对已有属性进行赋值     */        [self checkIsPropertyWithInstanceObject:instanceObject withPropertyName:@"titleName" withInstanceName:viewcontrollerName];        [self.navigationController pushViewController:(UIViewController *)instanceObject animated:YES];}#pragma mark 检测该对象是否包含该属性。包含就赋值。不包含就增加该属性,然后赋值-(void)checkIsPropertyWithInstanceObject:(id)instanceObject withPropertyName:(NSString *)propertyName withInstanceName:(NSString *)instanceName{    u_int count;        //获取该对象里面的所有属性    objc_property_t *propertys = class_copyPropertyList(object_getClass(instanceObject), &count);        //记录是否有目标属性    BOOL targetPropertyBool = NO;        //遍历属性    for (int i =0; i<count; i++) {        //获取属性名字        const char *charName = property_getName(propertys[i]);        //匹配目标属性(propertyName)名字        if ([[NSString stringWithCString:charName encoding:NSUTF8StringEncoding] isEqualToString:propertyName]) {            //kvc赋值            [instanceObject setValue:instanceName forKey:propertyName];            targetPropertyBool = YES;        }    }        /*     OBJC_ASSOCIATION_ASSIGN;            //assign策略     OBJC_ASSOCIATION_COPY_NONATOMIC;    //copy策略     OBJC_ASSOCIATION_RETAIN_NONATOMIC;  // retain策略          OBJC_ASSOCIATION_RETAIN;     OBJC_ASSOCIATION_COPY;     */    /*     *           objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);          id object 给哪个对象的属性赋值     const void *key 属性对应的key     id value  设置属性值为value     objc_AssociationPolicy policy  使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC     */        //该对象里面没有这个属性(propertyName)则动态添加该属性(propertyName)    if (!targetPropertyBool) {                const char *charPropertyName = [propertyName cStringUsingEncoding:NSASCIIStringEncoding];        objc_setAssociatedObject(instanceObject, charPropertyName, instanceName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);    }        free(propertys);}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}/*#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {    // Get the new view controller using [segue destinationViewController].    // Pass the selected object to the new view controller.}*/@end

0 0
原创粉丝点击