1.  

OC程序开发过程

#import预处理指令有两个作用:(1)与#include一样,拷贝文件内容(2)可以自动防止文件的内容被重复拷贝

程序编译连接过程:

源文件(.m)---(编译)---->目标文件(.0)-----(链接)---->可执行文件(.out)

Foundation框架。如果要使用框架中的所有头文件那么应该怎么办?包含框架的主头文件。主头文件是一个框架中最主要的头文件,每个框架的主头文件名和框架名一致。

如#import<foundation/foundation.h>

运行过程如下:

(1)编写OC源文件  .m .c

(2)编译文件  cc -c xx.m  xxx.c

(3)链接  cc xx.o xxx.o  -framework Foundation

(4)运行 ./a.out

文件编译

在工作中,通常把不同的类放到不同的文件中,每个类的声明和实现分开,声明写在.h头文件中,实现写在相应的.m文件中去,类名是什么,文件名的前缀就是什么。

假设有两个类,分别是Person类和Dog类,则通常有下面五个文件:

(1)Person.h    Person类的声明文件

(2)Person.m    Person类的实现文件

(3)Dog.h Dog类的声明文件

(4)Dog.m Dog类的实现文件

(5)Main.m 主函数(程序入口)

在主函数以及类的实现文件中要使用#import包含相应的头文件。

补充:import有两个作用:一是和include一样,完完全全的拷贝文件的内容;二是可以自动防止文件内容的重复拷贝(即使文件被多次包含,也只拷贝一份)。

在使用命令行进行编译链接文件的时候,通常是把.m文件单文件编译,然后再把所有的目标文件链接,但是在Xcode中,是把所有的.m文件都进行编译链接的,如果出现重复定义的错误,那大部分问题根源应该就是文件内容被重复包含或者是包含.m文件所引起的。

源文件中不论是使用include还是import,都不能包含.m或者是.c文件,只能放声明。因此,在OC中通常把类拆分开来,拆分成声明和实现两个部分。

提示:这也是编程思想的一种体现,可以说.h和.m文件时完全独立的,只是为了要求有较好的可读性,才要求两个文件的文件名一致,这也是把接口和实现分离,让调用者不必去关心具体的实现细节。

Xcode是写一行编译一行,有简单的修复功能,红色是错误提示,黄色警告。如果在程序中声明了一个变量,但是这个变量没有被使用也会产生警告信息。在调试程序的时候,如果发现整个页面都没有报错,但是一运行就错误,那么一定是链接报错。

RunTime运行时

runtime实现的机制是什么,怎么用,一般用于干嘛? 这个问题我就不跟大家绕弯子了,直接告诉大家, runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者 比如说,下面一个创建对象的方法中, 举例: OC : [[MJPerson alloc] init] runtime : objc_msgSend(objc_msgSend("MJPerson" , "alloc"), "init")

NSObject

@interface NSObject <NSObject> {

Class isa  OBJC_ISA_AVAILABILITY;//class

}

NSObject 只有一个成员isa 为class类型。

  1. /**
  2. * Describes the instance variables declared by a class.
  3. *
  4. * @param cls The class to inspect.
  5. * @param outCount On return, contains the length of the returned array.
  6. * If outCount is NULL, the length is not returned.
  7. *
  8. * @return An array of pointers of type Ivar describing the instance variables declared by the class.
  9. * Any instance variables declared by superclasses are not included. The array contains *outCount
  10. * pointers followed by a NULL terminator. You must free the array with free().
  11. *
  12. * If the class declares no instance variables, or cls is Nil, NULL is returned and *outCount is 0.
  13. */
  14.  
  15. /**
  16. * 描述类声明的实例变量
  17. *
  18. * @param cls 要检查的类
  19. * @param outCount 有返回 包含返回数组的长度
  20. * 如果 outCount 为空,长度没有返回
  21. *
  22. * 返回一个ivar类型的指针数组 ,描述这个类声明的实例变量
  23. * 任何父类声明的实例变量是不包括的 这个数组仅仅包含指针
  24. *如果指针为空,你必须用free()释放
  25. *
  26. * 如果这个类声明的不是实例变量,或者类为空 返回NULL outCount为0
  27. */
  28.  
  29. OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
  30. __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
  31. “遍历当前类所有的成员变量”
  32. ==================================================
  33. /* Working with Instance Variables */
  34.  
  35. /**
  36. * Returns the name of an instance variable.
  37. *
  38. * @param v The instance variable you want to enquire about.
  39. *
  40. * @return A C string containing the instance variable's name.
  41. */
  42. /* 操作实例变量 */
  43.  
  44. /**
  45. * 返回实例变量的名字.
  46. *
  47. * @param v 你想要查询的实例变量
  48. *
  49. * @return 一个C语言 字符串 包含实例变量的名字
  50. */
  51. OBJC_EXPORT const char *ivar_getName(Ivar v)
  52. __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
  53. “打印成员变量名字”
  54. ==================================================
  55.  
  56. /**
  57. * Returns the type string of an instance variable.
  58. *
  59. * @param v The instance variable you want to enquire about.
  60. *
  61. * @return A C string containing the instance variable's type encoding.
  62. *
  63. * @note For possible values, see Objective-C Runtime Programming Guide > Type Encodings.
  64. */
  65. /**
  66. * 返回一个实例变量的类型字符串。
  67. *
  68. * @param V 你想查询的实例变量。
  69. *
  70. * @return一个C语言字符串,包含实例变量的类型的 。
  71. *
  72. * @有价值的资料,看Objective-C编程指南>类型编码。
  73. */
  74.  
  75. OBJC_EXPORT const char *ivar_getTypeEncoding(Ivar v)
  76. __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
  77.  
  78. - (void)viewDidLoad {
  79. [super viewDidLoad];
  80. [self.view setBackgroundColor:[UIColor whiteColor]];
  81.  
  82. // 获得Person类中的所有成员变量
  83.  
  84. unsigned int count;
  85. Ivar *ivars = class_copyIvarList([runModel class], &count);
  86. for (int i = 0; i<count; i++) {
  87. Ivar ivar = ivars[i];
  88. const char *name = ivar_getName(ivar);
  89. const char *type = ivar_getTypeEncoding(ivar);
  90. NSLog(@"%s %s", name, type);
  91. }
  92.  
  93. }
  94.  
  95. ========================控制台打印结果========================
  96. 2016-07-22 16:15:22.086 runrunrun[20039:3797680] _age i
  97. 2016-07-22 16:15:22.086 runrunrun[20039:3797680] _name @"NSString"
  98. 2016-07-22 16:15:22.087 runrunrun[20039:3797680] _height @"NSString"
  99. 2016-07-22 16:15:22.087 runrunrun[20039:3797680] _weight @"NSString"
  100. 2016-07-22 16:15:22.087 runrunrun[20039:3797680] _sex @"NSNumber"
  101. // Created by Music on 16/7/12.
  102. // Copyright © 2016年 citibank. All rights reserved.
  103. //
  104.  
  105. #import <Foundation/Foundation.h>
  106.  
  107. @interface runModel : NSObject
  108.  
  109. @property (nonatomic ,copy)NSString *name;
  110. @property (nonatomic ,copy)NSString *height;
  111. @property (nonatomic ,copy)NSString *weight;
  112. @property (nonatomic ,assign)int age;
  113. @property (nonatomic ,strong)NSNumber *sex;
  114.  
  115. @end
  116. 分类加属性 应用运行时策略
  117.  
  118. #import "runModel.h"
  119. #import "Person.h"
  120.  
  121. @interface runModel (cate)
  122. @property (nonatomic ,strong)Person *height;
  123. - (void)test;
  124. @end
  125.  
  126. =============================
  127. #import "runModel+cate.h"
  128. #import <objc/runtime.h>
  129. @implementation runModel (cate)
  130.  
  131. - (void)test
  132. {
  133. NSLog(@"执行test分类方法");
  134. }
  135.  
  136. static double HeightKey;
  137.  
  138. - (void)setHeight:(Person *)height
  139. {
  140. objc_setAssociatedObject(self, &HeightKey, height, OBJC_ASSOCIATION_ASSIGN);
  141. }
  142.  
  143. - (Person *)height
  144. {
  145. return objc_getAssociatedObject(self, &HeightKey);
  146. }
  147.  
  148. @end
  149. ===================================
  150.  
  151. runModel *model = [[runModel alloc] init];
  152. model.height = p101;
  153. NSLog(@"---->>>%@",model.height);

runtime方法总结

1 获取类成员变量名,方法名称

  1. unsigned int count;
  2. Ivar *ivars = class_copyIvarList([runModel class], &count);

2 关联(分类添加属性)

  1. objc_setAssociatedObject(self, &HeightKey, height, OBJC_ASSOCIATION_ASSIGN);
  2. objc_getAssociatedObject(self, &HeightKey);

3 运行时添加方法

  1. class_addMethod(self, sel, (IMP)nameGetter, "@@:");

4 消息转发

  1. - (id)forwardingTargetForSelector:(SEL)aSelector{}

5 方法交换

  1. /** 获取原始setBackgroundColor方法 */
  2. Method originalM = class_getInstanceMethod([self class], @selector(setBackgroundColor:));
  3.  
  4. /** 获取自定义的pb_setBackgroundColor方法 */
  5. Method exchangeM = class_getInstanceMethod([self class], @selector(pb_setBackgroundColor:));
  6.  
  7. /** 交换方法 */
  8. method_exchangeImplementations(originalM, exchangeM);
  1.  

方法相关操作函数

Runtime提供了一系列的方法来处理与方法相关的操作。包括方法本身及SEL。本节我们介绍一下这些函数。

方法

  1. // 调用指定方法的实现
  2. id method_invoke ( id receiver, Method m, ... );
  3.  
  4. // 调用返回一个数据结构的方法的实现
  5. void method_invoke_stret ( id receiver, Method m, ... );
  6.  
  7. // 获取方法名
  8. SEL method_getName ( Method m );
  9.  
  10. // 返回方法的实现
  11. IMP method_getImplementation ( Method m );
  12.  
  13. // 获取描述方法参数和返回值类型的字符串
  14. const char * method_getTypeEncoding ( Method m );
  15.  
  16. // 获取方法的返回值类型的字符串
  17. char * method_copyReturnType ( Method m );
  18.  
  19. // 获取方法的指定位置参数的类型字符串
  20. char * method_copyArgumentType ( Method m, unsigned int index );
  21.  
  22. // 通过引用返回方法的返回值类型字符串
  23. void method_getReturnType ( Method m, char *dst, size_t dst_len );
  24.  
  25. // 返回方法的参数的个数
  26. unsigned int method_getNumberOfArguments ( Method m );
  27.  
  28. // 通过引用返回方法指定位置参数的类型字符串
  29. void method_getArgumentType ( Method m, unsigned int index, char *dst, size_t dst_len );
  30.  
  31. // 返回指定方法的方法描述结构体
  32. struct objc_method_description * method_getDescription ( Method m );
  33.  
  34. // 设置方法的实现
  35. IMP method_setImplementation ( Method m, IMP imp );
  36.  
  37. // 交换两个方法的实现
  38. void method_exchangeImplementations ( Method m1, Method m2 );
  1.  

runtime运行时的更多相关文章

  1. iOS - OC RunTime 运行时

    1.运行时的使用 向分类中添加属性 // 包含运行时头文件 #import <objc/runtime.h> /* void objc_setAssociatedObject(id obj ...

  2. RunTime 运行时

    简单介绍RunTime 运行时的用法 以下操作都需要导入头文件 #import <objc/message.h> #pragma mark -- 发消息 //OC方法调用的本质就是让对象发 ...

  3. iOS RunTime运行时(1):类与对象

    Objective-C语言是一门动态语言,他将很多静态语言在编译和链接期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码更具有灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一下 ...

  4. RunTime运行时在iOS中的应用之UITextField占位符placeholder

    RunTime运行时机制 runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的Objective-C代码中, 程序运行过程时, 其实最终 ...

  5. runtime运行时,类、对象、isa指针

    先查看一段OC源码,关于类的定义: /// An opaque type that represents an Objective-C class. typedef struct objc_class ...

  6. iOS运行时Runtime浅析

    运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...

  7. 【原】iOS动态性(五)一种可复用且解耦的用户统计实现(运行时Runtime)

    声明:本文是本人 编程小翁 原创,转载请注明. 为了达到更好的阅读效果,强烈建议跳转到这里查看文章. iOS动态性是我的关于iOS运行时的系列文章,由浅入深,从理论到实践.本文是第5篇.有兴趣可以看看 ...

  8. iOS 运行时runtime控制私有变量以及私有方法

    OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类.对象中的所有属性.方法,就算是私有方法以及私有属性都是可以动 ...

  9. Objective C运行时(runtime)

    #import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...

随机推荐

  1. 用rose画UML图(用例图,活动图)

    用rose画UML图(用例图,活动图) 首先,安装rose2003,电脑从win8升到win10以后,发现win10并不支持rose2003的安装,换了rose2007以后,发现也不可以. 解决途径: ...

  2. Python_猜大小

    # 需要在python3上执行 import random def game (capital = 1000): point1 = random.randrange(1,7) point2 = ran ...

  3. Bubble Cup 8 finals F. Bulbo (575F)

    题意: 给定初始位置,查询n次区间,每次查询前可以花费移动距离的代价来移动, 查询时需要花费当前位置到区间内最近的点的距离,求最小代价. 1<=n<=5000,1<=所有位置< ...

  4. Myeclipse不显示js文件错误的方法

    最近在学后台,用Myeclipse ,那么问题来了,Myeclipse 总是喜欢报 js 文件的错误,这就很烦了,看着也不舒服. 查看资料后,解决方法如下: 项目[鼠标右键] -> MyEcli ...

  5. iOS-Block总结 && 全面解析逆向传值

    1.block的特点:      block是C语言:      block是一种数据类型.可以当做参数,也可以用做返回值:--总之,对比int的用法用即可(当然,定义的时候,最好跟函数对比):   ...

  6. 如何改变span元素的宽度与高度

    内联元素:也称为行内元素,当多个行内元素连续排列时,他们会显示在一行里面. 内联元素的特性:本身是无法设置宽度和高度属性的,但是可以通过CSS样式来控制,达到我们想要的宽度和高度. span举例1: ...

  7. PAP认证方式原理和实现

    PAP认证协议 基本描述: Password Authentication Protocol 口令认证协议 PAP认证过程非常简单,二次握手机制,使用明文格式发送用户名和密码,发起方为被认证方,可以做 ...

  8. 基于SSH框架的网上商城的质量属性

    常见质量属性 1.性能 性能就是一个东西有多快,通常指响应时间或延迟. 响应时间:从发出请求到收到响应所用的时间,比如用户点击网页中的超链接或桌面应用程序中的按钮 延迟:消息从A点到B点,通过你的系统 ...

  9. [Python] from scipy import sparse 报 DLL load failed:找不到指定模块错误

    依赖vc运行环境.需要安装 vc_redist Py3.5要安装2015版 传送门: https://www.microsoft.com/zh-CN/download/details.aspx?id= ...

  10. 预处理命令[#define]说明

    宏定义 宏定义是对一些常见的变量.字符串等进行定义,被定义的数据在编译会进行自动替换.有时一些变量或字符串被多次使用,当需要修改时,就需要对源文件中它们出现的地方一一修改,效率比较低,而通过宏定义,只 ...