iOS运行时系统学习笔记

概述

iOS运行时(RunTime)系统以前一直听说,也自己看到各种大牛的技术博客学习过,自己也曾经敲过相关的代码,但是发现因为自己没有好好记录,因为学习不是一次性就可以完成的,导致效率并不高,不能很快的从上次学习的位置继续。我个人不擅长理论知识论述,关于运行时系统的理论相信网上已经有很多大牛已经详细介绍过了,我自己更多的是总结学习。所以,自己建立了个可以长久积累知识的工程,用来记录知识点,并且以代码为导向,通过用运行时的方法实现一些功能,达到验证理论知识和学习的目的,以后还是会增加新的代码的,希望和大家一起分享。因为工程内容主要是对理论知识的验证和运用,所以没有华丽的界面,所以的内容都是在控制台输出的。相信自己的注释在逻辑方法足够详细,也许对理论知识注释有所欠缺,但是相信每个人都能够根据上下文猜懂

链接:https://github.com/xiaobai1993/RunTimeTest


下面的类是BOOK类,这个类是自己主要验证运行时的一些方法所用的测试类,比如下面代码注释可以看到的,获取,修改类的属性,方法个数,参数和返回值等,并且通过这个类只声明了一些方法,并没有实现,通过运行时动态的转发机制处理错误,在不同的阶段分别解决崩溃问题。

@interface BOOK : NSObject
{
    NSString * ivarMember;//成员变量
}
@property (nonatomic,strong) NSString * name;
@property (nonatomic,assign) CGFloat price;
@property (nonatomic,strong) NSArray * authors;
@property (nonatomic,assign) int  pubishYear;

//---本类定义并且已经实现了的方法
-(void)printMessage;
//------运行时方法
-(NSArray*)allPropertyNames;//获取所有的属性变量
-(NSArray*)allPropertyAttr;//获取所有的属性变量的具体信息
-(NSArray*)allIvarNames;//所有的成员变量
-(void)allMethods;

//--测试运行时调用类中存在并实现的方法,这三个方法可以不再这里声明。运行时也能找到,并调用.
//第一层次
-(void)executeMethodByRunTime_00;
-(void)executeMethodByRunTime_01:(NSString *)param;
-(NSString *)executeMethodByRunTime_02:(NSString *)param;

//第二层次,调用没有实现的方法,利用运行时解决崩溃问题。

//这个房没有实现,只有声明,包含了两个参数和返回值,正常在外面调用时崩溃的,现在尝试用运行时采用多种不同的方式处理崩溃。并执行某些方法

//  resolveInstanceMethod 阶段解决未定义的方法
-(NSString *)onlyDeclareMethod:(NSString *)first andWithSec:(NSString*)second;
//测试在 - (id)forwardingTargetForSelector:(SEL)aSelector由其他类处理响应这个方法
-(NSString *)onlyDeclareMethod2:(NSString *)first andWithSec:(NSString*)second;
//测试在
-(NSString *)onlyDeclareMethod3:(NSString *)first andWithSec:(NSString*)second;

下面是具体的实现,实验的验证和原理已经在过程中注释,相信可以自己再过较长的时间也可以记得。代码的实现过程中遇到问题主要是查阅苹果文档,因为发现这部分的英文文档貌似没有自己想像的晦涩难懂

#import "BOOK.h"
#import 
#import 
#import "Pen.h"
#define MAXLength 100
@interface BOOK ()
{
    @private
    //私有的实例变量
    NSString * privateIvar;
}
//私有属性
@property (nonatomic,strong) NSString * privateProperty;
@end
@implementation BOOK

//类方法,本类定义的方法
//-------------------------------------------------------
-(void)printMessage
{
    NSLog(@"私有成员变量 privateIvar = %@",privateIvar);
}
//--------------------------------------------------------
//----属性和方法获取相关的内容  读和改

//获取所有的属性变量
/**
 property_getName获取属性名字
 */
-(NSArray*) allPropertyNames{
    NSMutableArray * pNames = [[NSMutableArray alloc]init];
    unsigned int count ;
    objc_property_t * propertys=class_copyPropertyList([self class], &count);
    for (int i = 0; iproperty_getAttributes 方法是关键
    "T@\"NSString\",&,N,V_name",
    "Td,N,V_price",
    "T@\"NSArray\",&,N,V_authors",
    "Ti,N,V_pubishYear"
 You can use the property_getAttributes function to discover the name, the @encode type string of a property, and other attributes of the property.
 The string starts with a T followed by the @encode type and a comma, and finishes with a V followed by the name of the backing instance variable. Between these, the attributes are specified by the following descriptors, separated by commas:
 --------
 T表示属性字符串开始,V表示结束,T后面是数据类型d表示的是double,逗号后面表示的是属性变量的类型,N表示nonatomic
 其他类型 Objective-C Runtime Programming Guide --> Type Encodings 和 Property Type String
 */
-(NSArray*)allPropertyAttr{
    NSMutableArray * pNamesAttr = [[NSMutableArray alloc]init];
    unsigned int count ;
    objc_property_t * propertys=class_copyPropertyList([self class], &count);
    for (int i = 0; i

Pen类主要的所有是验证运行时的消息转发,其他类替代自己处理事件,动态添加属性。

@interface Pen : NSObject
-(NSString *)onlyDeclareMethod2:(NSString *)first andWithSec:(NSString*)second;
-(NSString*)onlyDeclareMethod3:(NSString *)first andWithSec:(NSString *)second;

//替代BOOK实现的方法和这个方法参数不一致
-(NSString *)executeDefalut;
@end
@implementation Pen
-(NSString*)onlyDeclareMethod2:(NSString *)first andWithSec:(NSString *)second
{
  return  @"这是Pen类替代Book类实现了未实现的方法";
}
-(NSString*)onlyDeclareMethod3:(NSString *)first andWithSec:(NSString *)second
{
    return @"这是在forwardInvocation方法中实现由Pen对象替代BOOK对象执行未定义方法";
}
-(NSString*)executeDefalut
{
    return @"Pen代替Book实现了参数类型不一致的方法";
}
@end
@interface Pen (PenCate)
@property (nonatomic,strong) NSString * catePen;//类扩展属性
@end
static const char * catePen_Key ="cate_nameKey";
@implementation Pen (PenCate)
- (void)setCatePen:(NSString *)catePen
{
    //这个函数:Sets an associated value for a given object using a given key and association policy.
    //把一个值和一个对象用一个key和关联规则关联起来。第一个参数关联对象,第二个是key,第三个是关联的值,第四个关联规则,类似于
    //nonatomic,assin,copy,retain
    objc_setAssociatedObject(self, catePen_Key, catePen, OBJC_ASSOCIATION_RETAIN);
}
-(NSString*)catePen
{
    NSString * cateName= objc_getAssociatedObject(self, catePen_Key);//通过一个键值和对象取得对应的值。
    return cateName;
}
@end

你可能感兴趣的:(iOS运行时系统学习笔记)