MST

星途 面试题库

面试题:Objective-C实现命令模式时的内存管理考量

在Objective-C使用命令模式时,由于涉及对象的创建与交互,可能会引发内存管理问题。请举例说明在实现命令模式过程中,可能出现的内存泄漏场景,并阐述如何运用ARC(自动引用计数)或手动内存管理方式来避免这些问题。
13.9万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

可能出现的内存泄漏场景举例

假设我们有一个简单的命令模式实现,有一个Command类作为抽象命令类,ConcreteCommand类继承自Command,并且ConcreteCommand类在初始化时需要传入一个接收者对象Receiver。同时,有一个Invoker类来调用命令。

// Receiver类
@interface Receiver : NSObject
- (void)action;
@end

@implementation Receiver
- (void)action {
    NSLog(@"执行具体操作");
}
@end

// Command抽象类
@interface Command : NSObject
- (void)execute;
@end

// ConcreteCommand类
@interface ConcreteCommand : Command {
    Receiver *_receiver;
}
- (instancetype)initWithReceiver:(Receiver *)receiver;
@end

@implementation ConcreteCommand
- (instancetype)initWithReceiver:(Receiver *)receiver {
    if (self = [super init]) {
        _receiver = receiver;
    }
    return self;
}

- (void)execute {
    [_receiver action];
}
@end

// Invoker类
@interface Invoker : NSObject {
    Command *_command;
}
- (void)setCommand:(Command *)command;
- (void)invoke;
@end

@implementation Invoker
- (void)setCommand:(Command *)command {
    _command = command;
}

- (void)invoke {
    [_command execute];
}
@end

内存泄漏场景:在手动内存管理模式下,如果在Invoker类中设置了Command对象后,没有在合适的时机释放该Command对象(例如在Invoker类的dealloc方法中没有释放_command),就会导致内存泄漏。同样,如果ConcreteCommand类在持有Receiver对象时,没有在dealloc方法中释放_receiver,也会造成内存泄漏。

使用ARC避免内存泄漏

在ARC环境下,编译器会自动管理对象的内存。例如,上述代码无需开发者手动调用release等方法。当一个对象的引用计数变为0时,ARC会自动释放该对象。所以在ARC下,只要遵循正常的对象创建和引用规则,上述可能出现的内存泄漏场景就不会发生。

使用手动内存管理避免内存泄漏

  1. Invoker类中:在手动内存管理模式下,需要在Invoker类的dealloc方法中释放_command对象。
@implementation Invoker
- (void)dealloc {
    [_command release];
    [super dealloc];
}
// 其他方法不变
@end
  1. ConcreteCommand类中:同样,在ConcreteCommand类的dealloc方法中需要释放_receiver对象。
@implementation ConcreteCommand
- (void)dealloc {
    [_receiver release];
    [super dealloc];
}
// 其他方法不变
@end

通过在合适的位置释放对象,就可以避免在命令模式实现过程中的内存泄漏问题。