面试题答案
一键面试NSSet对象内存管理
- 引用计数:在ARC(自动引用计数)之前,Objective-C使用手动引用计数(MRC)。当向
NSSet
中添加对象时,对象的引用计数会增加;从NSSet
中移除对象时,对象的引用计数会减少。ARC下,编译器自动处理引用计数,添加到NSSet
中的对象被NSSet
强引用,当NSSet
释放时,其中的对象引用计数相应减少。 - 对象所有权:
NSSet
拥有其包含对象的所有权。如果一个对象被添加到多个NSSet
中,它的引用计数会因为多个NSSet
的强引用而增加。当所有引用该对象的NSSet
(以及其他可能的强引用)都释放时,对象才会被销毁。
优化包含大量自定义对象的NSSet性能
- 对象设计:
- 实现哈希方法:为自定义对象正确实现
hash
方法。NSSet
通过哈希值来快速定位对象,一个好的哈希方法能均匀分布哈希值,减少哈希冲突,提高查询效率。例如:
- 实现哈希方法:为自定义对象正确实现
- (NSUInteger)hash {
return self.uniqueID.hash; // 假设uniqueID是自定义对象的唯一标识属性
}
- **实现相等比较方法**:同时实现`isEqual:`方法,因为`NSSet`在判断对象是否重复或查找对象时会用到此方法。
- (BOOL)isEqual:(id)object {
if (self == object) return YES;
if (![object isKindOfClass:[self class]]) return NO;
CustomObject *other = (CustomObject *)object;
return self.uniqueID == other.uniqueID; // 根据唯一标识判断相等
}
- 内存管理:
- 使用弱引用:如果
NSSet
中的对象之间存在循环引用,可以使用弱引用来打破循环。例如,如果自定义对象内部有对NSSet
或其他对象的引用,可以将这些引用声明为weak
。
- 使用弱引用:如果
@property (nonatomic, weak) NSSet *relatedSet;
- **分批处理**:如果数据量非常大,可以考虑分批加载和处理数据,避免一次性将大量对象放入`NSSet`导致内存峰值过高。
3. 数据结构优化:
- 使用NSCountedSet
替代NSSet
(如果需要计数):如果需要统计每个对象在集合中出现的次数,可以使用NSCountedSet
。它继承自NSSet
,额外提供了计数功能,且在这种场景下性能可能更好。
- 考虑其他数据结构:对于某些特定需求,可以考虑其他数据结构。例如,如果需要有序的集合,可以使用NSOrderedSet
;如果更注重插入和删除性能,可以结合链表等数据结构来实现自定义的集合。