当前位置:首页 » 编程语言 » iosruntimec语言
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

iosruntimec语言

发布时间: 2022-11-27 01:02:52

1. ios 怎么用runtime来动态传值修改属性

首先定义一个类
#import@interface Person : NSObject
@property (assign, nonatomic) NSInteger age;
-(void)run;
@end

#import "Person.h"
@implementation Person
-(void)run{
NSLog(@"%s",__func__);
}
@end

定义分类
#import "Person.h"
@interface Person (Extention)
@property (, nonatomic) NSString *name;
-(void)saySex;
@end
#import "Person+Extention.h"
#import <objc/runtime.h>
@implementation Person (Extention)
//定义常量 必须是c语言字符串
static char *PersonNameKey = "PersonNameKey";
-(void)setName:(NSString *)name{
/*
OBJC_ASSOCIATION_ASSIGN; //assign策略
OBJC_ASSOCIATION_COPY_NONATOMIC; //策略
OBJC_ASSOCIATION_RETAIN_NONATOMIC; // retain策略

OBJC_ASSOCIATION_RETAIN;
OBJC_ASSOCIATION_COPY;
*/
/*
* id object 给哪个对象的属性赋值
const void *key 属性对应的key
id value 设置属性值为value
objc_AssociationPolicy policy 使用的策略,是一个枚举值,和,retain,assign是一样的,手机开发一般都选择NONATOMIC
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
*/

objc_setAssociatedObject(self, PersonNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)name{
return objc_getAssociatedObject(self, PersonNameKey);
}
-(void)saySex{
NSLog(@"%s----%@",__func__,self);
}

@end

总结:在分类中@property不会生成_变量,也不会实现getter和setter方法,我们可以手动实现如下
-(NSString *)name{
return @"name";
}
-(void)setName:(NSString *)name{

}

但是这样是没什么意义的,而且分类中不允许定义变量,所以只能用runtime类实现

2. 理解ios的runtime机制有什么用

一.RunLoop:

Runloop是事件接收和分发机制的一个实现。

Runloop提供了一种异步执行代码的机制,不能并行执行任务。

在主队列中,Main RunLoop直接配合任务的执行,负责处理UI事件、定时器以及其他内核相关事件。

(1).RunLoop的主要目的:

保证程序执行的线程不会被系统终止。

(2).什么时候使用Runloop ?

当需要和该线程进行交互的时候才会使用Runloop.

每一个线程都有其对应的RunLoop,但是默认非主线程的RunLoop是没有运行的,需要为RunLoop添加至少一个事件源,然后去run它。

一般情况下我们是没有必要去启用线程的RunLoop的,除非你在一个单独的线程中需要长久的检测某个事件。

主线程默认有Runloop。当自己启动一个线程,如果只是用于处理单一的事件,则该线程在执行完之后就退出了。所以当我们需要让该线程监听某项事务
时,就得让线程一直不退出,runloop就是这么一个循环,没有事件的时候,一直卡着,有事件来临了,执行其对应的函数。

RunLoop,正如其名所示,是线程进入和被线程用来相应事件以及调用事件处理函数的地方.需要在代码中使用控制语句实现RunLoop的循环,也就是说,需要代码提供while或者for循环来驱动RunLoop.

在这个循环中,使用一个runLoop对象[NSRunloop currentRunloop]执行接收消息,调用对应的处理函数.

Runloop接收两种源事件:input sources和timer sources。

input sources 传递异步事件,通常是来自其他线程和不同的程序中的消息;

timer sources(定时器) 传递同步事件(重复执行或者在特定时间上触发)。

除了处理input sources,Runloop
也会产生一些关于本身行为的notificaiton。注册成为Runloop的observer,可以接收到这些notification,做一些额外
的处理。(使用CoreFoundation来成为runloop的observer)。

Runloop工作的特点:

1>当有时间发生时,Runloop会根据具体的事件类型通知应用程序作出相应;

2>当没有事件发生时,Runloop会进入休眠状态,从而达到省电的目的;

3>当事件再次发生时,Runloop会被重新唤醒,处理事件.

提示:一般在开发中很少会主动创建Runloop,而通常会把事件添加到Runloop中.

二.Runtime:

RunTime简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制。对于C语言,函数的调用在编译的时候会决定调用哪个函数(
C语言的函数调用请看这里
)。编译完成之后直接顺序执行,无任何二义性。OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编
译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。只有在真正运行的时候才会根据函数的名称找
到对应的函数来调用。

那OC是怎么实现动态调用的呢?下面我们来看看OC通过发送消息来达到动态调用的秘密。假如在OC中写了这样的一个代码:

[objc] view plain?
<span style="font-size:18px;">[obj makeText];</span>
其中obj是一个对象,makeText是一个函数名称。对于这样一个简单的调用。在编译时RunTime会将上述代码转化成

[objc] view plain?
objc_msgSend(obj,@selector(makeText));
首先我们来看看obj这个对象,iOS中的obj都继承于NSObject。

[objc] view plain?
@interface NSObject <nsobject> {
Class isa OBJC_ISA_AVAILABILITY;
}</nsobject>
在NSObjcet中存在一个Class的isa指针。然后我们看看Class:

[objc] view plain?
typedef struct objc_class *Class;
struct objc_class {
Class isa; // 指向metaclass

Class super_class ; // 指向其父类
const charchar *name ; // 类名
long version ; // 类的版本信息,初始化默认为0,可以通过runtime函数class_setVersion和class_getVersion进行修改、读取
long info; // 一些标识信息,如CLS_CLASS (0x1L) 表示该类为普通 class ,其中包含对象方法和成员变量;CLS_META (0x2L) 表示该类为 metaclass,其中包含类方法;
long instance_size ; // 该类的实例变量大小(包括从父类继承下来的实例变量);
struct objc_ivar_list *ivars; // 用于存储每个成员变量的地址
struct objc_method_list **methodLists ; // 与 info 的一些标志位有关,如CLS_CLASS (0x1L),则存储对象方法,如CLS_META (0x2L),则存储类方法;
struct objc_cache *cache; // 指向最近使用的方法的指针,用于提升效率;
struct objc_protocol_list *protocols; // 存储该类遵守的协议
}

我们可以看到,对于一个Class类中,存在很多东西,下面我来一一解释一下:

Class
isa:指向metaclass,也就是静态的Class。一般一个Obj对象中的isa会指向普通的Class,这个Class中存储普通成员变量和对
象方法(“-”开头的方法),普通Class中的isa指针指向静态Class,静态Class中存储static类型成员变量和类方法(“+”开头的方
法)。

Class super_class:指向父类,如果这个类是根类,则为NULL。

下面一张图片很好的描述了类和对象的继承关系:

注意:所有metaclass中isa指针都指向跟metaclass。而跟metaclass则指向自身。
Root metaclass是通过继承Root class产生的。与root class结构体成员一致,也就是前面提到的结构。不同的是Root
metaclass的isa指针指向自身。

3. runtime实现的机制是什么,有哪些用法,一般用于干嘛

runtime库里面包含了跟类、成员变量、方法相关的API,比如获取类里面的所有成员变量,为类动态添加成员变量,动态改变类的方法实现,为类动态添加新的方法等 需要导入<objc/message.h><objc/runtime.h>1.是什么

1> runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API

2> 平时编写的OC代码, 在程序运行过程中, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者

3> 举例:

OC :

[[MJPerson alloc] init]runtime :

objc_msgSend(objc_msgSend("MJPerson" , "alloc"), "init")2.用过么? 怎么用?

1> runtime是属于OC的底层, 可以进行一些非常底层的操作(用OC是无法现实的, 不好实现)

* 在程序运行过程中, 动态创建一个类(比如KVO的底层实现)

* 在程序运行过程中, 动态地为某个类添加属性方法, 修改属性值方法

* 遍历一个类的所有成员变量(属性)所有方法3.相关的头文件和函数

1> 头文件

* <objc/runtime.h>

* <objc/message.h>2> 相关应用

* NSCoding(归档和解档, 利用runtime遍历模型对象的所有属性)

* 字典 --> 模型 (利用runtime遍历模型对象的所有属性, 根据属性名从字典中取出对应的值, 设置到模型的属性上)

* KVO(利用runtime动态产生一个类)

* 用于封装框架(想怎么改就怎么改)3> 相关函数

* objc_msgSend : 给对象发送消息

* class_MethodList : 遍历某个类所有的方法

* class_IvarList : 遍历某个类所有的成员变量

* class_.....

4. 运行(run)模式工作原理

工作原理是 Objective-C是一门动态语言,它会将一些工作放在代码运行时才处理而并非编译时。
Runtime又叫运行时,是一套底层的C语言API,其为iOS内部的核心之一,我们平时编写的OC代码,底层都是基于它来实现的。

5. iOS之runtime详解api(一)

runtime 在iOS中是“运行时”的含义,是一套用c语言写的api,很多人会用但是也仅仅用过最最常用的几个函数,这次,我将详细的带着大家探索下 runtime 的API,这一章就说下 <objc/runtime.h> 这个文件里的 API ,并且我会把不适用于 ARC 和不支持64位的API剔除掉。

首先,我们先看一个简单的函数:

这个函数是通过传入 Class 类型的 cls 来得到 Class 的名字。那我们测试下这个函数:

其中 [Person class] OC中获得 Class 的方法,当然,你也可以用 runtime 里面的 objc_getClass 等函数,后面我也会讲到。
运行结果:

我们可以看到打印出来的结果就是类的名字。
上面既然用到了 [Person class] ,那我们就看下在 runtime 中 [Person class] 的替代函数,都是通过名字来获得 Class

那这三个有什么区别,从结论上讲, objc_getClass 和 objc_lookUpClass 的效果是一致的,在最新的源码里面,这两个方法调用的底层也是一致的,当你要找的类不存在的话,就返回nil,而 objc_getRequiredClass 里你要找的类不存在的话,就会崩溃。下面我们来测试下,我们创建一个 Person 类。

运行结果:

最后也确实崩溃了,所以大家使用 objc_getRequiredClass 这个函数时候要慎重小心。
除了用名字获得类对象以外,还可以用实例对象来获取:

我们测试下:

运行结果:

完全没问题。
Class 不仅可以代表类对象,也可以代表元类对象,下面这个函数就是通过名字获取元类对象。

如果你读过源码的话,你就会清楚元类对象储存的是类方法,类对象储存的是实例方法,在后面讲到Method相关的API的时候,我们在具体讲他们之间的区别。

讲到元类对象,我们还要关注下这个函数,

这个函数是用来判断是否是元类对象。

运行结果:

我们可以看到 objc_getMetaClass 生成才是元类对象, objc_getClass 生成的只是类对象。
那么有没有函数区分类(元类)对象和实例对象呢?当然有:

这个方法只要是类对象或者元类对象都会返回YES:

运行结果:

当然也可以获得父类对象。

我们新建一个继承 Person 的类 Student ,然后我们通过 Student 类来获得 Person 类。

运行结果:

Student 的父类确实是 Person 。

我们知道OC里面可以强转类型,当然, runtime 里面也有相关方法

这个方法的意思是给一个实例对象设置新的类,返回旧的类

运行结果:

我们可以看出开始的时候 student 的类是 Student ,用了 object_setClass 后就是 Person 类了。
runtime 的动态性还可以动态新增类,下面四个函数分别表示为一个类分配内存,注册一个类,复制一个类,销毁一个类

创建一个新类, superclass 是新类所继承的类,如果为 nil , superclass 就默认为根类,也就是 NSObject , extraBytes 是在类和元类对象的末尾为索引ivars分配的字节数。这一般是0, name 是新类的名字。

注册类,如果这个类 objc_allocateClassPair 好了,就必须 objc_registerClassPair 才能使用。

这个方法在系统KVO的底层用过,系统不推荐我们自己用。

objc_disposeClassPair 只能销毁通过 objc_allocateClassPair 创建的类。
我们写个demo来测试这些方法, objc_plicateClass 官方不建议使用,那么我们就不测试这函数。

运行结果:

我们可以知道如果仅仅只是 objc_allocateClassPair 的话,你是找不到这个类的,必须再 objc_registerClassPair 才可以找到, objc_disposeClassPair 则是把类销毁掉,所以再实际开发中,如果我们不再使用自建类的时候,就要及时销毁,节省内存。

下面两个函数是关于整个工程的类列表的函数:

这个函数是获得所有注册类的列表,我们试用下:

运行结果:

我们看到注册的类有15765个。
objc_getClassList 也是获取注册类的方法.

第一个参数 buffer 已分配好内存空间的数组指针, bufferCount 是数组的个数,如果 bufferCount 的数量小于实际的数组数量,那么 buffer 返回的是所有数组集合的任意一个子类。如果 buffer 为NULL,那么 bufferCount 为0。无论那种情况,返回结果都是当前注册类的总数。

运行结果:

返回类实例的大小。

运行结果

一个没有变量或属性的继承于NSObject的类占有8个字节。
还有个方法是:

这是一个创建实例的方法, cls 是要创建的类, extraBytes 是额外的字节内存,用来存储类定义中的实例变量之外的其他实例变量。在源码中 alloc 方法底层就是用的这个函数。那么,我们用这个函数来初始化 Person 类:

运行结果:

确实能够成功创建出来。
最后剩下两个方法:

这两个方法都和 version 有关,这个version在实际中我也没发现用处,可能是在改变类的变量或者方法时给定一个标识.

运行结果

下面我们将使用runtime里面最最常用的api,也就是给分类绑定对象,这里,我们先了解下,一个枚举:

objc_AssociationPolicy 是一个枚举,里面的枚举值分别代表要添加的属性的修饰类型。
OBJC_ASSOCIATION_ASSIGN 相当于 weak
OBJC_ASSOCIATION_RETAIN_NONATOMIC 相当于 strong 和 nonatomic
OBJC_ASSOCIATION_COPY_NONATOMIC 相当于 和 nonatomic
OBJC_ASSOCIATION_RETAIN 相当于 strong 和 atomic
OBJC_ASSOCIATION_COPY 相当于 和 atomic
关于分类的runtime函数,主要有下面3个:

含义分别为设置关联对象,获得关联对象,删除关联对象。
我们知道如果在分类的 .h 文件设置属性并没有用,调用的时候会发生闪退,这是因为系统并没有自动为属性生成 Set 和 Get 方法,所以,我们用上面三个方法来手动关联对象。
我们创建一个 Person 的分类 Person+Actor.h ,在.h文件里新建一个新属性 @property(nonatomic, assign)float actingSkill 而不做其他任何处理,这时候, .m 文件就会有警告。

这时候就绑定好了。
在 ViewController 里面去使用下这个属性

运行结果:

说明set和get方法都成功了。
那么还有一个 objc_removeAssociatedObjects 方法还没用,这个方法是解除绑定,为了测试这个效果,我们在ViewController里面 touchesBegan 里面去调用这个方法。

运行结果:

之前绑定的结果被移除了。
今天我们这一篇就讲到这, runtime 还有很多其他的用法我们下一篇见。
对了,这个是 demo ,喜欢的可以点个星。

6. c语言编程时当出现runtime erro时要怎么办一般是什么原因!

Runtime是运行时的意思,Runtime
Error就是运行时错误,就是在运行期间出现的错误。
webopedia
关于
运行时错误的定义:
运行时错误是程序执行期间发生的错误,它不同于编译期间发生的错误.运行时错误可能是程序中的毛病引起的,也可能程序并无错误,例如机器存储器不够引起
所以:很有可能是你对内存的操作出现了问题。多检查指针方面的代码,看是不是有问题

7. C语言报错出现runtime error如何处理

RuntimeError常见出错的原因可能有以下几种:

1、数组开得太小了,导致访问到了不该访问的内存区域

2、发生除零错误

3、大数组定义在函数内,导致程序栈区耗尽

4、指针用错了,导致访问到不该访问的内存区域

5、还有可能是程序抛出了未接收的异常

转自CSDN网页链接

8. C语言Runtime Error的原因是什么

runtime error (运行时错误)就是程序运行到一半,程序就崩溃了。
原因有很多,比如说:①除以零②数组越界:int a[3]; a[10000000]=10;③指针越界:int * p; p=(int *)malloc(5 * sizeof(int)); *(p+1000000)=10;④使用已经释放的空间:int * p; p=(int *)malloc(5 * sizeof(int));free(p); *p=10;⑤数组开得太大,超出了栈的范围,造成栈溢出:int a[100000000];

根据经验,大多数情况是因为程序员对内存的理解不透彻导致错误应用引起的~

9. iOS Runtime理解

 runtime

概述: runtime又叫运行时,是一套底层C语言API,是iOS系统的核心之一。开发者在编码过程中,可以给任意一个对象发送消息,在编译阶段只是确定了要向接受着发送这条消息,而接受者如何响应和处理这条消息,就要看运行时来决定了

 C语言中,在编译器就确定要调用哪个函数,而OC的函数,属于动态调用过程,在编译器并不能真正决定调用哪个函数,只有在真正的运行时才会根据函数的名称找到对应的函数来调用。OC是一个动态语言,这意味着它不仅要一个编译器,也需要一个运行时系统来动态创建类和对象、进行消息传递和发送

1.消息转发

Runtime的特性主要是消息传递,如果消息在对象中找不到,就进行转发。Objective-C是一个动态语言,这意味着它不仅需要一个编译器,也需要一个运行时系统来动态创建类和对象、进行消息传递和转发。Runtime的核心是消息传递。

(1)消息传递的过程

一个对象的方法[obj test],编译器转成消息发送objc_msgSend(obj,test),Runtime执行的流程是这样的

a.首先通过obj的isa指针找到它的class

b.在class的method list找test

c.如果class中没找到test,继续往它的superclass中找

d.一旦找到test这个函数,就去执行它的IMP

由于效率问题,每个消息都遍历一次objc_method_list并不合理,所以需要把经常被调用的函数缓存下来,去提高函数查询的效率。这也就是objc_class中另一个重要的成员objc_cache做的事情。找到test之后,将test的method_name作为key,method_imp作为value。当再次收到test消息的时候,可以直接在cache里找。

类对象(objc_class)

Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。struct objc_class结构体里面定义了很多变量。结构体里保存了指向父类的指针、类的名字(name)、版本、实例变量列表(ivars)、方法列表(methodLists)、缓存(cache)、遵守的协议列表(protocols),由此可见,类对象就是一个结构体struct objc_class,这个结构体存放的数据就是元数据

理解Runtime就是理解iOS在运行时他的数据存储以及他的类、实例、类对象、元类她们之间的关系和作用。

(2)消息转发机制

归根到底,Objective-C中所有的方法调用本质就是向对象发送消息

1.类中创建方法-(void)test

2.iOS系统为这个方法创建一个编号,SEL(test)并添加到方法列表里面

3.当调用这个方法的时候系统去方法列表里查找这个方法,找到了就执行

所以,调用一个方法就会进行一次发送消息也就是在这个类的方法列表里找,如果在该类中找不到就到该类的父类里找,如果父类还找不到就一直搜索到继承树的根部,如果找不到或者消息转发不成功那就会报unrecognized selector错。

1.动态方法解析

Objective-C运行时会调用+resolveInstanceMethod:或者 +resolveClassMethod:让你有机会提供一个函数实现,如果你添加了函数并且返回YES,那么运行时就会重新启动一次消息发送的过程。如下图:

虽然没有foo:的实现函数,但是通过class_addMethod()动态添加了fooMethod函数,并执行了这个函数并且打印成功。如果reslove返回NO运行时就会移到下一步:forwardingTargetSelector

2.直接消息转发

如果目标对象实现了forwardingTargetSelector,Runtime这时就会调用这个方法,给你把这个消息转发给其他对象的机会

从图中可以看出我们通过forwardingTargetForSelector方法将当前类的方法转给Father类实现了,打印成功。

3.完整消息转发

如果在上一步还不能处理未知消息,那唯一能做的就是启动消息转发机制。首先它会发送methodSignatureForSelector消息获得函数的参数和返回值类型。如果methodSignatureForSelector返回nil,Runtime则会发出doesNotRecognizeSelector。如果返回一个签名函数,Runtime就会创建一个NSInvocation对象并发送forwardInvocation消息给目标对象。

Runtime的实际应用

1.使用Runtime交换方法

2.动态添加方法(目前不是很懂)

3.给分类添加属性

4.消息转发(热更新)解决Bug(JSPatch)

10. 学习iOS开发C语言要学哪些基础知识

C语言是一种计算机程序设计语言。它既有高级语言的特点,又具有汇编语言的特点。它可以作为系统设计语言, 编写工作系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。因此,它的应用范围广泛。 C语言在很多方面都可以用,不仅仅是在软件开发上,各类科研都是需要用到C语言的。C语言是最受欢迎的语言之一。iOS开发网络全书—C语言网络
1.编程入门
首先介绍C语言的学习路线、环境搭建、iOS编程的行业前景、计算机的基本工作原理,为刚入门的初学者做铺垫,有一个基本概念,方便以后的学习。
2.C语言的基本概念
对学习路线中的各个阶段的是知识点有个简单的了解,并用项目的形式展示出我们学习之后可以做的事情,后续剧情先知先觉,学时豁然开朗,轻松接收。
3.格式化输入输出与基本类型
介绍了最基本的输入输出、进制、整形、浮点型、字符型的数据及其转换,用最简单的方式编最简单的C程序。
4.流程控制
介绍了流程的基本概念、分支语句、循环语句的概念、基本语法、与应用。程序如何判断,判断的条件,把我们解决问题的流程放进程序中表达的基本课程。
5.函数
详细介绍了函数的基本概念,函数的组成,函数的用法。高效编程,一劳永逸,把简单的功能模块化,函数就是利器。