property的本质

@property 的本质是什么

1、“属性” (property)作为 Objective-C 的一项特性,主要的作用就在于封装对象中的数据。“属性” (property)有两大概念:ivar(实例变量)、存取方法(access method = getter + setter)。

2、property在runtime中是objc_property_t定义:

typedef struct objc_property *objc_property_t;

weak属性需要在dealloc中置nil么?

在ARC环境无论是强指针还是弱指针都无需在 dealloc 设置为 nil , ARC 会自动帮我们处理.

在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。

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

“自动合成”( autosynthesis)

完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)

也可以在类的实现代码里通过 @synthesize 语法来指定实例变量的名字.

1
2
3
4
@implementation Person
@synthesize firstName = _myFirstName;
@synthesize lastName = _myLastName;
@end

@protocol 和 category 中如何使用 @property

category 使用 @property 也是只会生成 setter 和 getter 方法的声明,如果我们真的需要给 category 增加属性的实现,需要借助于运行时的两个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#import "NSObject+Person.h"
#import <objc/runtime.h> /*或者 #import <objc/message.h>*/
static NSString *nameKey = @"nameKey"; //那么的key

@interface NSObject ()

@end

@implementation NSObject (Person)

/**
setter方法
*/
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY);
}

/**
getter方法
*/
- (NSString *)name {
return objc_getAssociatedObject(self, &nameKey);
}
@end

分类并不会改变原有类的内存分布的情况,它是在运行期间决定的,此时内存的分布已经确定,若此时再添加实例会改变内存的分布情况,这对编译性语言是灾难,是不允许的。反观扩展(extension),作用是为一个已知的类添加一些私有的信息,必须有这个类的源码,才能扩展,它是在编译器生效的,所以能直接为类添加属性或者实例变量。

在 protocol 中使用 property 只会生成 setter 和 getter 方法声明,我们使用属性的目的,是希望遵守我协议的对象能实现该属性。

类扩展(Class Extension)

Extension是Category的一个特例。类扩展与分类相比只少了分类的名称,所以称之为“匿名分类”。

其实开发当中,我们几乎天天在使用。对于有些人来说像是最熟悉的陌生人。作用是:为一个类添加额外的原来没有变量,方法和属性。

@interface XXX ()
//私有属性
//私有方法(如果不实现,编译时会报警,Method definition     for 'XXX' not found)
@end