MST

星途 面试题库

面试题:Objective-C中Category的语法限制有哪些

请详细阐述Objective-C类别(Category)在语法方面存在哪些限制,例如对成员变量、方法声明等方面的限制。
17.0万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

对成员变量的限制

  • 无法直接声明实例变量:在Category中不能直接声明实例变量(Instance Variable)。例如,在一个类Person的Category中,如下代码会报错:
@interface Person (ExtraInfo) {
    NSString * _nickname; // 报错,不能在Category中声明实例变量
}
@end

这是因为Category主要目的是为已有的类添加新的方法,而非扩展类的属性存储。

对方法声明的限制

  • 无法覆盖原有方法:虽然可以在Category中声明与类中原有方法同名的方法,但并不会覆盖原有方法,而是会在运行时根据方法的调用顺序等规则来决定最终调用哪个方法。例如:
@interface Person : NSObject
- (void)sayHello;
@end

@implementation Person
- (void)sayHello {
    NSLog(@"Original Hello");
}
@end

@interface Person (NewBehavior)
- (void)sayHello;
@end

@implementation Person (NewBehavior)
- (void)sayHello {
    NSLog(@"New Hello");
}
@end

当调用[Person new] sayHello]时,调用的是Category中实现的方法(在实际复杂情况下,方法决议等机制会影响最终调用哪个sayHello方法,但原则是不会覆盖)。

  • 不能声明@property@synthesize@dynamic:在Category中可以声明@property,但不能使用@synthesize@dynamic。例如:
@interface Person (ExtraProperties)
@property (nonatomic, copy) NSString *hobby;
// 不能在这里写 @synthesize hobby; 或 @dynamic hobby;
@end

需要手动提供存取方法的实现来处理这个@property。通常,在Category中声明的@property,需要通过关联对象(Associated Objects)来实现其存储。

其他限制

  • 无法添加协议(Protocol):Category本身不能添加新的协议供类遵循。如果要让类遵循新的协议,需要在类的主接口声明处添加协议遵循。例如,不能在Category中像下面这样写:
@interface Person (ExtraProtocol) <NewProtocol> // 错误,Category不能添加协议
@end

若要让Person类遵循NewProtocol,应在Person类的主接口@interface Person : NSObject <NewProtocol>处添加。