面试题答案
一键面试初始化NSMapTable
在Objective-C中,使用NSMapTable
存储键值对并对值采用弱引用,初始化如下:
NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory];
这里NSPointerFunctionsStrongMemory
表示键使用强引用,NSPointerFunctionsWeakMemory
表示值使用弱引用。
添加键值对
添加键值对可以使用setObject:forKey:
方法:
id key = [[NSObject alloc] init];
id value = [[NSObject alloc] init];
[mapTable setObject:value forKey:key];
获取键值对
获取键值对使用objectForKey:
方法:
id retrievedValue = [mapTable objectForKey:key];
移除键值对
移除键值对使用removeObjectForKey:
方法:
[mapTable removeObjectForKey:key];
多线程环境下的考虑
- 线程安全:
NSMapTable
本身不是线程安全的。在多线程环境下,同时进行读写操作可能导致数据竞争和未定义行为。 - 解决方案:
- 使用锁:可以使用
NSLock
或@synchronized
块来保护对NSMapTable
的操作。例如:
- 使用锁:可以使用
NSLock *lock = [[NSLock alloc] init];
// 添加操作
[lock lock];
[mapTable setObject:newValue forKey:newKey];
[lock unlock];
// 获取操作
[lock lock];
id retrievedValue = [mapTable objectForKey:key];
[lock unlock];
- **使用队列**:利用`dispatch_queue_t`,将对`NSMapTable`的所有操作都放在同一个队列中执行,保证操作的顺序性,避免竞争条件。
dispatch_queue_t queue = dispatch_queue_create("com.example.mapTableQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
[mapTable setObject:newValue forKey:newKey];
});