Effective Objective-C - 对象、消息、运行期
前言
Effective Objective-C 2.0 系列读书笔记最后一篇
笔记
理解“属性”这一概念
下面两部分代码等效
1
2
3
4
5
6
7
8
9
10@interface EOCPerson : NSObject
@property NSString *firstName;
@end
@interface EOCPerson : NSObject {
NSString *_firstName;
}
- (NSString *)firstName;
- (void)setFirstName:(NSString *)firstName;
@end可以理解成:属性 = 实例变量 + 存取方法
可以改变属性生成的实例变量的名字:
1
2
3@implementation EOCPerson
@synthesize firstName = _myFirstName;
@end将实例变量命名成
_myFirstName
,不再使用默认的名字当然还可以不让编译器自动生成存取方法,就是使用dynamic
1
2
3@implementation EOCPerson
@dynamic firstName;
@end此时不会自动生成存取方法,也不会自动创建实例变量。在编译访问属性的代码时,也不会出错,因为编译器相信能在运行期找到对应的方法
具备readonly特性的属性仅拥有获取方法,只有当该属性由
@synthesize
实现时,编译器才会为其合成获取方法拥有与非拥有 是针对指针与内存空间来说的:
1
@property (nonatomic, strong) NSString *strPointer;
上面的语句说明:有一个NSString指针,如果他指向一块存放NSString的内存,那么strPointer指针拥有该内存。该内存的reference count加1
copy 对于NSString来说特别有用,特别是在NSString和NSMutableString之间转换的时候。需要注意的是在初始化方法中,初始化该属性也要使用copy方法
1
2
3
4
5
6- (id)initWithFirstName:(NSString *)firstName {
if (self = [super init]) {
_firstName = [firstName copy];
}
return self;
}不应该在init方法中调用存取方法。
iOS中的同步锁性能开销较严重,所以一般使用的nonatomic属性
在对象内部尽量直接访问实例变量
- 直接访问实例变量和通过存取方法来访问的区别
- 直接访问不经过方法派发,速度更快
- 直接访问时不会经过设置方法,绕过了内存管理语义。例如:在ARC下直接方法一个copy属性,那么不会拷贝该值,只会retain
- 直接访问不会触发KVO
- 折中的方案:设置时使用设置方法,读取时直接访问
理解“对象等同性”这一概念
- 应该使用NSObject协议中的
isEqual
方法来判断对象的等同性。可以对象自己实现isEqual
来精确判断 - 当然对于特殊的对象可以使用更精确的方法
以“类族模式”隐藏实现细节
- UIButton有一个类方法:
+ (UIButton *)buttonWithType:(UIButtonType)type;
该方法返回的对象类型根据type不同而不同,但是基类都是UIButton - 类族的基类一般没有 init 方法,提示用户:这种类不需要用户自己去创建。
- 调用
isMemberOfClass:
的时候不会返回YES,因为不是UIButton,只是它的子类 - NSArray就是类族
在既有类中使用关联对象存放自定义数据
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.