面试题答案
一键面试1. Objective - C属性访问器方法命名语法规则在runtime层面的实现原理
在Objective - C中,属性(property)通过访问器方法(accessor methods)来实现对实例变量的访问。属性访问器方法分为getter(获取值)和setter(设置值)方法。
-
命名规则:
- Getter方法:对于非布尔类型属性,默认getter方法名为属性名,例如属性
customProperty
,其默认getter方法为- (CustomType)customProperty
。对于布尔类型属性,若属性名以is
开头,默认getter方法名为属性名,否则getter方法名前缀为is
,例如isValid
属性,其getter方法为- (BOOL)isValid
。 - Setter方法:默认setter方法名为
set
加上属性名首字母大写,例如customProperty
属性,其setter方法为- (void)setCustomProperty:(CustomType)newValue
。
- Getter方法:对于非布尔类型属性,默认getter方法名为属性名,例如属性
-
runtime层面实现:在runtime中,编译器会自动为属性生成对应的访问器方法实现代码。当通过点语法或者直接调用访问器方法访问属性时,runtime会根据方法名查找对应的实现。例如,当调用
self.customProperty
时,runtime会查找- (CustomType)customProperty
方法;当调用self.customProperty = value
时,runtime会查找- (void)setCustomProperty:(CustomType)value
方法。runtime通过类的方法列表来查找方法的实现,如果类本身没有找到对应的方法,会沿着继承体系向上查找。
2. 对频繁读写的customProperty
属性进行优化思路及实现步骤
优化思路
- 减少方法调用开销:方法调用在Objective - C中涉及到runtime的消息发送机制,存在一定的开销。对于频繁读写的属性,可以考虑直接访问实例变量来减少方法调用。
- 正确的内存管理:在直接访问实例变量时,要确保内存管理的正确性。如果
customProperty
是对象类型,需要遵循内存管理规则(ARC或MRC)。
实现步骤
假设CustomType
是一个对象类型,并且项目使用ARC(自动引用计数)。
- 直接访问实例变量:在类的实现文件中,可以直接访问实例变量。如果没有显式声明实例变量,编译器会自动为属性生成一个带下划线的实例变量,例如
_customProperty
。
@interface MyClass : NSObject
@property (nonatomic, strong) CustomType *customProperty;
@end
@implementation MyClass
// 优化后的读操作
- (CustomType *)customProperty {
return _customProperty;
}
// 优化后的写操作
- (void)setCustomProperty:(CustomType *)newValue {
if (_customProperty != newValue) {
_customProperty = newValue;
}
}
@end
在上述代码中,读操作直接返回实例变量_customProperty
,写操作先检查新值与旧值是否相同,避免不必要的赋值,从而提高性能。同时,由于使用ARC,内存管理由编译器自动处理,保证了内存管理的正确性。
如果项目使用MRC(手动引用计数),则需要在setter方法中手动管理内存:
@implementation MyClass
// 优化后的读操作
- (CustomType *)customProperty {
return _customProperty;
}
// 优化后的写操作
- (void)setCustomProperty:(CustomType *)newValue {
if (_customProperty != newValue) {
[_customProperty release];
_customProperty = [newValue retain];
}
}
- (void)dealloc {
[_customProperty release];
[super dealloc];
}
@end
在MRC下,setter方法中对旧值调用release
,对新值调用retain
,在dealloc
方法中释放_customProperty
,确保内存管理的正确性。