MST

星途 面试题库

面试题:Objective-C类别在代码扩展中的方法重写问题

在Objective-C中,如果在类别(Category)里重写了类的原有方法,会有什么影响?请举例说明如何在不影响原有类实现的情况下,利用类别为其添加新功能且避免方法冲突。
38.3万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. 在类别(Category)里重写类的原有方法的影响
    • 在Objective - C中,当在类别里重写类的原有方法时,运行时类别中的方法会覆盖原有类的方法。这意味着当调用该方法时,实际执行的是类别中的方法,而不是原有类中的方法。这可能会破坏原有类的预期行为,特别是当原有类的一些功能依赖于该方法的原始实现时。例如,假设有一个Person类,它有一个description方法用于返回人的基本信息:
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
- (NSString *)description;
@end

@implementation Person
- (NSString *)description {
    return [NSString stringWithFormat:@"Name: %@, Age: %ld", self.name, (long)self.age];
}
@end
  • 然后创建一个Person类的类别,并在类别中重写description方法:
@interface Person (Category)
- (NSString *)description;
@end

@implementation Person (Category)
- (NSString *)description {
    return @"This is a person from category.";
}
@end
  • 当使用Person类的实例调用description方法时,会执行类别中的实现,而不是原有类中的实现:
Person *person = [[Person alloc] init];
person.name = @"John";
person.age = 30;
NSLog(@"%@", person);
// 输出:This is a person from category.
  1. 在不影响原有类实现的情况下,利用类别为其添加新功能且避免方法冲突
    • 为了避免方法冲突,可以在类别方法名上使用独特的前缀。例如,为Person类添加一个新的打招呼功能:
@interface Person (NewFunction)
- (void)person_customGreeting;
@end

@implementation Person (NewFunction)
- (void)person_customGreeting {
    NSLog(@"Hello, my name is %@ and I'm %ld years old.", self.name, (long)self.age);
}
@end
  • 这样,在使用Person类的实例时,可以调用新添加的方法而不会影响原有类的方法:
Person *person = [[Person alloc] init];
person.name = @"Jane";
person.age = 25;
[person person_customGreeting];
// 输出:Hello, my name is Jane and I'm 25 years old.
  • 另外,还可以使用关联对象(Associated Objects)为类添加额外的属性,同时避免命名冲突。例如,为Person类添加一个favouriteColor属性:
#import <objc/runtime.h>

@interface Person (ExtraProperty)
@property (nonatomic, strong) NSString *favouriteColor;
@end

@implementation Person (ExtraProperty)
- (void)setFavouriteColor:(NSString *)favouriteColor {
    objc_setAssociatedObject(self, @selector(favouriteColor), favouriteColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSString *)favouriteColor {
    return objc_getAssociatedObject(self, @selector(favouriteColor));
}
@end
  • 使用时:
Person *person = [[Person alloc] init];
person.favouriteColor = @"Blue";
NSLog(@"My favourite color is %@", person.favouriteColor);
// 输出:My favourite color is Blue