如果用来修饰对象的话,当被修饰的对象释放后,assign修饰的属性指针不会置为nil,成为野指针。如果后续这块地址被分配,再使用该属性则会crash(Error:EXC_BAD_ACCESS)。...“属性定义”就相当于“类”和“待设置的属性值”之间达成的契约。 注意:如果自己来实现时,应保证其具备属性所声明的特质。...另外如果想在其他方法里设置属性值时,也同样需要遵循属性定义中宣称的语义。 ...assign变量在指向变量释放后不会置为nil,再使用会crash。而weak会置为nil。 weak和strong的区别? 当一个对象还有strong类型的指针指向时,不会被释放。...当实例对象存在weak指针指向自己时,系统会为这个实例创建一个子类,将这个实例的isa指正指向子类,然后重写dealloc方法,在dealloc方法中添加清除weak指针操作(以当前对象内存地址为key
,可以理解为一个“事件”:当目标对象销毁时,同时要发生的“事件”。...// .h文件 // .h文件 // 这个类,可以理解为一个“事件”:当目标对象销毁时,同时要发生的“事件”。借助block执行“事件”。...因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本....如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性. copy 此特质所表达的所属关系与 strong 类似。...(自动合成)又失效了,如果不去手动定义ivar,那么你就得借助 @synthesize 来手动合成 ivar。
三、编程题:实现以下功能 1) 编写一个自定义类:Person,父类为NSObject 解析:头文件这样写 @interface Person:NSObject 2) 该类有两个属性,外部只读的属性name...age的修饰符nonatomic,copy。 3) 为该类编写一个初始化方法 initWithName:(NSString *)nameStr,并依据该方法参数初始化name属性。...编译的时候自动的为name属性生成一个实例变量_name 如果m中什么都不写,xcode会默认在编译期为 market 属性,补全成 @synthesize market = _market,实例变量名为...总之,当修饰可变类型的属性时,如NSMutableArray、NSMutableDictionary、NSMutableString,用strong。...当修饰不可变类型的属性时,如NSArray、NSDictionary、NSString,用copy。 4.7 题目: 分类中添加实例变量和属性分别会发生什么,编译时就报错吗,还是什么时候会发生问题?
假如一个属性被声明为 @dynamic var,然后你没有提供@setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到instance.var = someVar,由于缺 setter...a.因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本....b.如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性. aa.在非集合类对象中:对 immutable 对象进行 copy 操作,是指针复制...(自动合成)又失效了,如果不去手动定义ivar,那么你就得借助@synthesize来手动合成 ivar。...当使用 self 调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用 super 时,则从父类的方法列表中开始找。然后调用父类的这个方法。
获取指定类的属性以及父类的所有属性 /** 获取指定类的属性 @param cls 被获取属性的类 @return 属性名称 [NSString *] */ NSArray * getClassProperty...]; } /** 获取指定类(以及其父类)的所有属性 @param cls 被获取属性的类 @param until_class 当查找到此类时会停止查找,当设置为 nil 时,默认采用...]; } 获取指定类以及其父类所有的变量 /** 获取指定类的变量 @param cls 被获取变量的类 @return 变量名称集合 [NSString *] */ NSArray * getClassIvar...free(iv); return [all_p copy]; } /** 获取指定类(以及其父类)的所有变量 @param cls 被获取变量的类 @param...until_class 当查找到此类时会停止查找,当设置为 nil 时,默认采用 [NSObject class] @return 变量名称集合 [NSString *] */ NSArray *
步骤: 1、为UIImage建一个分类(UIImage+Category) 2、在分类中实现一个自定义方法,方法中写要在系统方法中加入的语句,比如版本判断 + (UIImage *)xh_imageNamed...注意,下面的代码我换了一个方法名(不然会覆盖系统原来的方法!),加了一个忽略属性方法是否被实现的判断,并加上了对父类属性的归解档循环。...:方法防止报错),模型属性是一个对象或者数组时不好处理等问题,所以无论是效率还是功能上,利用runtime进行字典转模型都是比较好的选择。...字典转模型我们需要考虑三种特殊情况: 1.当字典的key和模型的属性匹配不上 2.模型中嵌套模型(模型属性是另外一个模型对象) 3.数组中装着模型(模型的属性是一个数组,数组中是一个个模型对象)...,这时候由于属性没有对应值会被赋值为nil,就会导致crash,我们只需加一个判断即可,JSON数据和sample如下: ?
字典转模型:KVC 当对象的属性很多的时候,我们可以利用KVC批量设置。...* 返回值: 所有属性的数组, C 语言中,数组的名字,就是指向第一个元素的地址 */ /* retain, creat, copy 需要release */ objc_property_t...Ivar *ivarList = class_copyIvarList(self, &count); // 2.遍历所有的成员属性名,一个一个去字典中取出对应的value给模型属性赋值...2.3 对2.1的改进:2.1无法对多层数据进行转换 思路:可以模仿2.2中的递归,对2.1进行改进:模型中,除了为数组属性添加数组元素对应的类名映射字典,还要为模型属性对应的类名添加映射字典。...这是因为,从字典遍历出来的key无法得知自定义类型的属性的类名。
步骤: 1、为UIImage建一个分类(UIImage+Category) 2、在分类中实现一个自定义方法,方法中写要在系统方法中加入的语句,比如版本判断 + (UIImage *)xh_imageNamed...注意,下面的代码我换了一个方法名(不然会覆盖系统原来的方法!),加了一个忽略属性方法是否被实现的判断,并加上了对父类属性的归解档循环。...:方法防止报错),模型属性是一个对象或者数组时不好处理等问题,所以无论是效率还是功能上,利用runtime进行字典转模型都是比较好的选择。...字典转模型我们需要考虑三种特殊情况: 1.当字典的key和模型的属性匹配不上 2.模型中嵌套模型(模型属性是另外一个模型对象) 3.数组中装着模型(模型的属性是一个数组,数组中是一个个模型对象) 根据上面的三种特殊情况...= dict[key]; // 如果模型属性数量大于字典键值对数理,模型属性会被赋值为nil而报错 if (value == nil) continue; // 将字典中的值设置到模型上
2、作用 1.动态交换两个方法的实现 2.为类别添加属性(我们知道类别是不能扩展属性的,只能扩展方法,但可以运行时实现,通过为类增加属性) 3.获取某个类的所有成员变量和成员方法 4.实现NSCoding...的自动归档和自动解档 5.动态添加对象的成本变量和成员方法 作用:当硬件内存过小的时候,如果我们将每个方法都直接加到内存当中去,但是几百年不用一次,这样就造成了浪费,所有采取动态添加 6.实现字典和模型的自动转换...,变量名理所当然也是object const void *key :获取被关联者的索引key id value :被关联者,这里是一个...block objc_AssociationPolicy policy : 关联时采用的协议,有assign,retain,copy等协议,一般使用OBJC_ASSOCIATION_RETAIN_NONATOMIC...edcode和decode了,如果几十个属性一个个的encode和decode真的很麻烦啊,使用运行时可以遍历出每个对象的属性,数组的方式遍历eccode,decode) #import "DWPerson.h
之前我写过两篇文章详细介绍过KVC的用法: KVC详解(上) KVC详解(下) 这篇文章是在上述两篇文章的基础上做一个原理性的补充。 首先呢,我们来聊一聊苹果开发文档。...现在我就以查找KVC官方文档为例,演示一下如何在苹果官方文档中找到想要的内容。...(nonatomic, copy)NSArray *terchers; @end 现在我要修改norman.terchers中的第一个元素,如下: Norman *norman = [Norman...通过KVC来存取自定义结构体 LavieStruct是一个自定义的结构体,Norman类中定义了一个LavieStruct类型的属性: typedef struct { NSString *...自定义KVC 苹果只给我们提供了KVC的文档,并没有将KVC的源码开源出来。因此,为了加深理解,我按照官方文档的步骤说明,自定义了一个简易版的KVC。
为这个类增加一个方法。在这个方法中打印一些值。 通过这个类的实例调用新增的方法。...需要注意的是,如果如本例中,ivar_getName()获取的值前面有_ 是属性变量,前面没有下划线的是实例变量(包括隐藏起来的私有变量和.h 中公开的实例变量)。...特别说明下: 方式1中的以类别的形式为一个类增加属性,在调用环境中必须满足两个条件,否则会报错。...交换一个类的两个方法的实现 如果将originMethod与currentMethod的方法实现进行交换的话, 调用originMethod时就会执行currentMethod的内容。 ?...,当项目的需求发生改变时,要使用另一种功能代替这个功能,且要求不改变旧的项目(也就是不改变原来方法实现的前提下)。
运行时的文章一直被同学们热炒,当然现在面试中也都喜欢问道,当大伙说的头头是道时候,可到真正的项目中几乎局限只会关联对象或者MethodSwizzling奉为神剑到处挥砍,开发毕竟不能纸上谈兵,实践出真知...1.2 相关函数 //为一个实例对象添加一个关联对象,由于是C函数只能使用C字符串,这个key就是关联对象的名称,value为具体的关联对象的值,policy为关联对象策略,与我们自定义属性时设置的修饰符类似...JSPatch 为代表的热修复技术被开发者推崇,通过逆向中国市面上有头有脸的iOS应用,我发现几乎都使用JSPath或者JSPath的变种。...就是我们常说的消息转发, 举一个栗子,我在工作中项目出现了差错,本着挽救同志的目的,领导让我立即马上提供一次挽回的方法,如果我给力这个危机到此没了,但是我跪了搞不定,领导就问谁可以解决,这是老王站了出来...NSLog(@"\n name = %s \n type = %s", ivar_getName(ivar),ivar_getTypeEncoding(ivar)); } KVC 修改属性值
;他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。...假如一个属性被声明为dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var = someVar,由于缺 setter方法会导致程序崩溃...;或者当运行到someVar = var时,由于缺 getter方法同样会导致崩溃。...同时重写了setter和getter时,系统就不会生成ivar,使用@synthesize foo =_foo;关联@property 与ivar 重写了只读属性的getter 时 使用了@dynamic...时 在@protocol中定义的所有属性 在category中定义的所有属性 重载的属性,当在子类中重载了父类中的属性,必须使用@synthesize来手动合成ivar objc中向一个nil对象发送消息将会发生什么
我们在开发中常常使用类目Category为一些已有的类扩展功能。...遗憾的是,OC的类目并不支持直接添加属性,如果我们直接在分类的声明中写入Property属性,那么只能为其生成set与get方法声明,却不能生成成员变量,直接调用这些属性还会造成崩溃。...现在演示一个代码示例:为UIImage增加一个分类:UIImage+Tools,并为其设置关联属性urlString(图片网络链接属性),相关代码如下: //UIImage+Tools.h文件中 UIImage...+Tools.m @interface UIImage (Tools) //添加一个新属性:图片网络链接 @property(nonatomic,copy)NSString *urlString; @end...return objc_getAssociatedObject(self, @selector(urlString)); } //添加一个自定义方法
属性是指对象的特性。 属性声明? 属性声明是一种声明变量为属性的语法。 属性的实现? 声明了实例变量或定义了相应的访问方法(存取方法)即为实现了属性。..._age); } @end 那个警告明显是说,我自动合成的实例变量是__age,而不是 _age,所以你应该定义一个 __age 的实例变量才对,不然我就警告你; 其实这里是间接地证明了,如果你自己定义了相应的带下划线的实例变量...; 当然 age 那个错误可以直接忽略,因为压根就不会有它的出现; 当然如果只手动做一个方法的实现: ?...因为这里 age 默认是 readwrite 的,所以肯定还有两个方法(存取),如果只手动实现其中一个,就相当于告诉 Xcode 我还有一个方法你帮我实现了吧; 那么如果属性是 readonly 的呢?...,是一个结构体,下面看看它的属性描述定义: /// Defines a property attribute typedef struct { const char *name;
在介绍消息机制之前,我还是要再啰嗦一点,关于@selector()我们还需要深入理解一下,通过@selector(方法名)可以获取到一个SEL类型的对象,SEL实际上是objc_selector结构体指针...因此SEL也可以理解为函数签名,在程序的编译阶段,我们定义类中所有所发会生成一个方法签名列表,这个列表时类直接关联的(原则上来说,类的本质也是对象,它是一个单例对象),在运行时通过方法签名表来找到具体要执行的函数...当消息转发策略也被否定后,系统会调用methodSignatureForSelector方法,这个方法的主要用途是询问这个选择器是否是有效的,我们需要返回一个NSMethodSignature,顾名思义...顺便说一下,如果你没有使用任何救命稻草,当向某个对象发送了无法处理的消息时,系统会最终调用到NSObject类的doesNotRecognizeSelector方法,这个方法会抛出异常信息,正因如此,你在.../* 属性特指使用@prototype定义的 objc_property_t是一个结构体指针,其描述的是属性的信息,如下: typedef struct { const char *name;
1.3获取某个类的实例变量 如果你还需要获取某个类的实例变量做什么操作的话,可以使用如下这几个API: // 获取实例变量数组 Ivar * class_copyIvarList(Class cls,...,它能让开发者对已经存在的类在扩展中添加自定义的属性。...,但是我们通过Associated Objects可以间接的实现往类上添加自定义的属性。...这里如果我们为AlertView 或者ActionSheet 添加Category来实现的话,代码跟上面为Son 添加类别基本一样,对象类型改为id 类型即可。...OC 自动生成分类属性方法 一个库--DProperty 4.运行时动态创建一个类 我在某控制器中测试写了这么一个方法,来创建一个MyClass 类。项目中并不存在叫MyClass 的类文件。
Tech 导读 通过分析Foundation框架中的KVC部分并结合案例分析KVC原理,解释为什么属性为简单数据类型的时候可以设置其值为字符串类型且不会崩溃的真实原因。...01 前言 在今年的敏捷团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!...,类中属性为Integer 第一反应是崩溃,因为OC是类型敏感的。...如果1,2没有找到对应的方法和属性则调用 valueForUndefinedKey:并抛出异常 4....图6 应用场景 项目中的细节如下:修改拒收数量时更新总妥投数和总拒收数、勾选明细更新总妥投数和总拒收数、全选、清空、反选。如果用通常的做法是每次操作都要循环去计算总数和记录选择状态。
property.代表OC声明的属性 typedef struct objc_property *objc_property_t; // Class代表一个类,它在objc.h中这样定义的 typedef...,对一个类进行了完全的分解,将类定义或者对象的每一个部分都抽象为一个类型type,对操作一个类属性和方法非常方便。...super_class:这个指针就是指向该class的super class,即指向父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL。...一个接收者对象接收到一个消息时,它会根据isa指针去查找能够响应这个消息的对象。在实际使用中,这个对象只有一部分方法是常用的,很多方法其实很少用或者根本用不上。...动态为Category扩展加属性 XCode运行你在Category的.h文件申明@Property,编译通过,但运行时如果没有Runtime处理,进行赋值取值,就马上报错。
我们看输出的v24@0:8@16,分析上面的说明就可以知道: v24返回类型为viod,@0接收器类型为id,@16参数类型为id 至于类型后面的值观察可以发现都是相差8,我认为是在method中的位置...我们创建一个 ClassA 的分类 ClassA+CategoryA ,在 ClassA+CategoryA 中添加一个属性 name #import "ClassA.h" @interface ClassA...,参数如下: object:属性关联的源对象,这里使用了self,代表关联本类的对象 key:区分属性的唯一标识,因为关联的属性可能不止一个,我们使用了- (NSString *)name方法的SEL...当然,平时使用我们并不会这么做,当我们要在系统提供的方法上再扩充功能时(不能重写系统方法),就可以使用Method Swizzling....下面我面添加一个名为resolveThisMethodDynamically的方法: void dynamicMethodIMP(id self, SEL _cmd) { // implementation
领取专属 10元无门槛券
手把手带您无忧上云