面试题答案
一键面试问题分析
在多线程环境下,多个线程同时对NSMutableArray
进行添加和删除操作,可能会导致数据竞争问题。例如,一个线程正在添加元素时,另一个线程同时进行删除操作,这可能会导致数组内部状态不一致,引发程序崩溃或数据丢失等问题。
实现思路
- 使用锁机制:可以使用
NSLock
、NSRecursiveLock
、dispatch_semaphore
等锁来保证同一时间只有一个线程能够访问和修改mutableArray
。 - 原子操作:虽然
NSMutableArray
本身不是线程安全的,但可以通过将其封装在一个线程安全的类中,利用原子属性来保证部分操作的原子性,但对于复杂的添加和删除操作,锁机制更可靠。
关键代码示例
- 使用NSLock
#import <Foundation/Foundation.h>
@interface ThreadSafeArray : NSObject
@property (nonatomic, strong) NSMutableArray *mutableArray;
@property (nonatomic, strong) NSLock *arrayLock;
- (void)addObject:(id)object;
- (void)removeObject:(id)object;
@end
@implementation ThreadSafeArray
- (instancetype)init {
self = [super init];
if (self) {
_mutableArray = [NSMutableArray array];
_arrayLock = [[NSLock alloc] init];
}
return self;
}
- (void)addObject:(id)object {
[self.arrayLock lock];
[self.mutableArray addObject:object];
[self.arrayLock unlock];
}
- (void)removeObject:(id)object {
[self.arrayLock lock];
[self.mutableArray removeObject:object];
[self.arrayLock unlock];
}
@end
- 使用dispatch_semaphore
#import <Foundation/Foundation.h>
#import <dispatch/dispatch.h>
@interface ThreadSafeArray : NSObject
@property (nonatomic, strong) NSMutableArray *mutableArray;
@property (nonatomic, assign) dispatch_semaphore_t semaphore;
- (void)addObject:(id)object;
- (void)removeObject:(id)object;
@end
@implementation ThreadSafeArray
- (instancetype)init {
self = [super init];
if (self) {
_mutableArray = [NSMutableArray array];
_semaphore = dispatch_semaphore_create(1);
}
return self;
}
- (void)addObject:(id)object {
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
[self.mutableArray addObject:object];
dispatch_semaphore_signal(self.semaphore);
}
- (void)removeObject:(id)object {
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
[self.mutableArray removeObject:object];
dispatch_semaphore_signal(self.semaphore);
}
@end
在上述代码中,ThreadSafeArray
类封装了NSMutableArray
,并通过锁机制(NSLock
或dispatch_semaphore
)来确保对mutableArray
的添加和删除操作在多线程环境下的线程安全性。在使用时,创建ThreadSafeArray
的实例,然后通过调用其addObject:
和removeObject:
方法来进行线程安全的操作。