美文网首页IOS 基础知识iOS 高级
iOS 属性关键字进阶篇

iOS 属性关键字进阶篇

作者: wnido | 来源:发表于2018-03-10 19:31 被阅读90次

之前写过 《iOS属性关键字》基础篇,便于初学者理解,但没有从根本上去说明,属性的本质,这次就更进一步说明

属性的本质

 ivar + getter + setter
  • ivar 实例变量
  • 存取方法(access method = getter + setter)

直白一点说,每个属性本身就是一个实例的封装,getter 和 setter 方法,就是这个实例开放给外界的外部接口,
我们可以根据 getter 和 setter 方法,访问这个实例。

举个例子:

@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@end

上述代码写出来的类与下面这种写法等效:

@interface Person : NSObject
- (NSString *)firstName;
- (void)setFirstName:(NSString *)firstName;
- (NSString *)lastName;
- (void)setLastName:(NSString *)lastName;
@end

runtime 中对属性的更新

property 在 runtime 中是 objc_property_t 定义如下:

typedef struct objc_property *objc_property_t;

而 objc_property 是一个结构体,包括 name 和 attributes,定义如下:

struct property_t {
    const char *name;
    const char *attributes;
};

这这其中 attributes 本质是 objc_property_attribute_t ,定义了 property 的一些属性,定义如下:

/// Defines a property attribute
typedef struct {
    const char *name;           /**< The name of the attribute */
    const char *value;          /**< The value of the attribute (usually empty) */
} objc_property_attribute_t;

而 attributes 的具体内容是什么呢?其实,包括:类型,原子性,内存语义和对应的实例变量

例如:

我们定义一个 string 的 property @property (nonatomic, copy) NSString *string;,
通过 property_getAttributes(property)获取到 attributes 并打印出来之后的结果为 T@"NSString",C,N,V_string

其中 T 就代表类型,可参阅 Type Encodings C 就代表 Copy,N 代表 nonatomic,V 就代表对于的实例变量。

ivar、getter、setter 是如何生成并添加到这个类中的?

“自动合成”( autosynthesis)

完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”( autosynthesis )。需要强调的是,这个过程由编译器在编译期执行,所以编辑器里看不到这些“合成方法”( synthesized method )的源代码。除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。在前例中,会生成两个实例变量,其名称分别为 _firstName 与 _lastName。也可以在类的实现代码里通过 @synthesize 语法来指定实例变量的名字.

@implementation Person
@synthesize firstName = _myFirstName;
@synthesize lastName = _myLastName;
@end

其实相关的代码,会大致生成了五个东西

  • OBJC_IVAR_$类名$属性名称 :该属性的“偏移量” (offset),这个偏移量是“硬编码” (hardcode),表示该变量距离存放对象的内存区域的起始地址有多远。
  • setter 与 getter 方法对应的实现函数
  • ivar_list :成员变量列表
  • method_list :方法列表
  • prop_list :属性列表

我们每次在增加一个属性:

  • 系统首先会在 ivar_list 中添加一个成员变量的描述
  • 在 method_list 中增加 setter 与 getter 方法的描述,
  • 在属性列表中增加一个属性的描述

然后计算该属性在对象中的偏移量,然后给出 setter 与 getter 方法对应的实现,在 setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值 , 为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转.

反过来推一推一个程序如何从空到有

这里为什么会用 “空” ,而不是 “无”,因为我们所有的创造都不是完全从无开始的,像一个人也不是从无到有的,一个人的诞生也是从空到有,必须有“空”,至于什么是 “空”,就不赘述。
一个程序的诞生,必须先要有内存空间,这个内存空间就是整个程序的原点,也是它的空。而如何让空的东西变成有,我们就要赋予它规则,有规则后,才能一生二,二生三,三生万物,这便是天地最根本的道理。而程序,也是遵循这个道理,更透彻的说,一段程序,就是承载一段有规律 0 和 1 的集合。

😓本质总是这样简单又复杂


结束语

实际上,这本身就是一种封装,便于开发者更简单实现,基础类的定义;这也是为什么 OC 代码的编写方式 和 C 代码编写方式的不一样的地方。

相关文章

  • iOS 属性关键字进阶篇

    之前写过 《iOS属性关键字》基础篇,便于初学者理解,但没有从根本上去说明,属性的本质,这次就更进一步说明 属性的...

  • iOS属性关键字

    iOS属性关键字 引言 学习 iOS 开发的人,大多都绕不开属性关键字—— assign,weak,unsafe_...

  • iOS开发---属性关键字详解

    iOS开发—属性关键字详解 @Property 什么是属性? 属性(property)是Objective-C的一...

  • iOS runtime从菜鸟到应用(小灰进阶篇)

    iOS runtime从菜鸟到应用(小灰进阶篇) iOS runtime从菜鸟到应用(小灰进阶篇)

  • 属性关键字-(进阶篇)

    上一篇文章基础篇,我们用NSMutableString为例详细讲解了“非容器可变变量”。相信大家都已经基本掌握了重...

  • iOS objective-c 属性关键字

    首先iOS objective - C有以下属性关键字strongweakassignatomicnonatomi...

  • iOS - 基础

    iOS 属性修饰关键字都有哪些? atomic 原子性访问,对属性赋值的时候加锁 noatomic 非原子...

  • ios9新特性(关键字)

    嗯嗯,马上就要 发布iOS新的版本了。嗯,码农又该忙碌了 ios9新特性(关键字) 新出的关键字:修饰属性,方法的...

  • iOS 中weak的实现

    只要学过 iOS 的人,都会对 strong、weak、copy等关键字应该都会很熟悉。weak 属性关键字就是弱...

  • IOS 常用关键字基础大全

    ios声明属性时,在ARC环境下常用到的关键字,readonly、readwrite、nonatomic、...

网友评论

    本文标题:iOS 属性关键字进阶篇

    本文链接:https://www.haomeiwen.com/subject/qvubfftx.html