内存管理
- 自动引用计数(ARC):
- 在ARC环境下,编译器会自动处理对象的内存管理。访问者和元素对象的内存会在它们不再被引用时自动释放。例如,当访问者访问元素对象完成后,若访问者和元素对象没有其他强引用指向它们,ARC会自动释放其内存。
- 示例代码:
// 假设这是一个元素类
@interface Element : NSObject
@end
@implementation Element
@end
// 假设这是一个访问者类
@interface Visitor : NSObject
- (void)visitElement:(Element *)element;
@end
@implementation Visitor
- (void)visitElement:(Element *)element {
// 访问逻辑,在ARC下不用担心element的内存释放,当方法结束且无其他强引用时,element会被自动释放
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Visitor *visitor = [[Visitor alloc] init];
Element *element = [[Element alloc] init];
[visitor visitElement:element];
// 这里ARC会自动处理visitor和element的内存释放
}
return 0;
}
- 手动引用计数(MRC,在ARC之前的方式):
- 当使用MRC时,访问者在访问元素对象时,需要遵循引用计数规则。例如,访问者获取元素对象的引用后,若要持有该对象一段时间,需要调用
retain
方法增加引用计数,使用完毕后调用release
方法减少引用计数。
- 示例代码:
// 元素类
@interface Element : NSObject
@end
@implementation Element
- (void)dealloc {
[super dealloc];
}
@end
// 访问者类
@interface Visitor : NSObject
- (void)visitElement:(Element *)element;
@end
@implementation Visitor
- (void)visitElement:(Element *)element {
[element retain];
// 访问逻辑
[element release];
}
- (void)dealloc {
[super dealloc];
}
@end
int main(int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Visitor *visitor = [[Visitor alloc] init];
Element *element = [[Element alloc] init];
[visitor visitElement:element];
[element release];
[visitor release];
[pool release];
return 0;
}
线程安全
- 锁机制:
- 互斥锁(NSLock):可以使用
NSLock
来确保在同一时间只有一个线程能够访问共享资源(如访问者和元素对象的交互逻辑)。
- 示例代码:
// 元素类
@interface Element : NSObject
@property (nonatomic, strong) NSLock *elementLock;
@end
@implementation Element
- (instancetype)init {
self = [super init];
if (self) {
_elementLock = [[NSLock alloc] init];
}
return self;
}
- (void)acceptVisitor:(Visitor *)visitor {
[self.elementLock lock];
[visitor visitElement:self];
[self.elementLock unlock];
}
- (void)dealloc {
[_elementLock release];
[super dealloc];
}
@end
// 访问者类
@interface Visitor : NSObject
@property (nonatomic, strong) NSLock *visitorLock;
- (void)visitElement:(Element *)element;
@end
@implementation Visitor
- (instancetype)init {
self = [super init];
if (self) {
_visitorLock = [[NSLock alloc] init];
}
return self;
}
- (void)visitElement:(Element *)element {
[self.visitorLock lock];
// 访问逻辑
[self.visitorLock unlock];
}
- (void)dealloc {
[_visitorLock release];
[super dealloc];
}
@end
- GCD(Grand Central Dispatch):
- 使用GCD的队列来串行化对共享资源的访问。例如,创建一个串行队列,将访问者和元素对象的交互任务提交到该队列中执行。
- 示例代码:
// 元素类
@interface Element : NSObject
@property (nonatomic, strong) dispatch_queue_t elementQueue;
@end
@implementation Element
- (instancetype)init {
self = [super init];
if (self) {
_elementQueue = dispatch_queue_create("com.example.elementQueue", DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (void)acceptVisitor:(Visitor *)visitor {
dispatch_sync(self.elementQueue, ^{
[visitor visitElement:self];
});
}
- (void)dealloc {
dispatch_release(_elementQueue);
[super dealloc];
}
@end
// 访问者类
@interface Visitor : NSObject
- (void)visitElement:(Element *)element;
@end
@implementation Visitor
- (void)visitElement:(Element *)element {
// 访问逻辑
}
@end
- 原子属性(Atomic Properties):
- 若元素对象或访问者对象中有共享的属性,将这些属性声明为原子属性。例如,
@property (nonatomic, atomic, strong) SomeObject *sharedProperty;
,原子属性会自动生成锁代码来确保属性访问的线程安全性。但要注意,原子属性只能保证属性访问的原子性,对于复杂的操作仍需要额外的同步机制。
- 示例代码:
// 元素类
@interface Element : NSObject
@property (nonatomic, atomic, strong) NSString *sharedString;
@end
@implementation Element
@end