Почему метод экземпляра NSObject может быть вызван как метод класса

#ios #objective-c #swift

#iOS #цель-c #swift

Вопрос:

Я добавляю категорию для NSObject

 @interface NSObject (Test)
- (nonnull NSString *)nameOfClass;
@end
@implementation NSObject (Test)
-(NSString *)nameOfClass {
    return [self new_nameOfClass];
}
@end
 

при использовании я могу использовать его как функцию класса.

 Objc
[UITableViewCell nameOfClass];
swift
UITableViewCell.nameOfClass()
 

но если я создам подкласс NSObject и добавлю функцию с использованием category

 @interface TestObject : NSObject
@end
@interface TestObject (Test)
- (nonnull NSString *)testFunction;
@end
@implementation NSObject (Test)
-(NSString *) testFunction {
    return @"testFunction";
}
@end
 

Я не могу использовать его как

 [TestObject testFunction];
 

если я создам расширение для NSObject

 @objc
public extension NSObject {
    @objc(new_nameOfClass)
    func new_nameOfClass() -> String {
        return String(describing: type(of: self))
    }
}
 

Я могу использовать его как функцию класса в файле Objc, но. Я не могу использовать его в swift.

 [TestObject new_nameOfClass]; 

TestObject.new_nameOfClass()
error: Instance member 'new_nameOfClass' cannot be used on type 'TestObject'; did you mean to use a value of this type instead?
 

Вопросы

  1. почему функция экземпляра категории NSObject может использоваться как функция класса?
  2. почему это не работает в подклассе NSObject?
  3. почему расширение swift для NSObject не имеет. такое же поведение?

пожалуйста, обратитесь к этим документам. http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html
http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html

Комментарии:

1. FWIW у вас может быть как класс, так и функция экземпляра в Objective-C с тем же именем. Это может сбить вас с толку, если вы оба определили случайно.

2. Я думаю, это будет полезно: cocoawithlove.com/2010/01 /…

3. @Cy-4AH спасибо, это действительно хорошо для меня

Ответ №1:

сделайте эту функцию функцией класса

objective c

  @interface TestObject : NSObject
    @end
    @interface TestObject (Test)
      (nonnull NSString *)testFunction;
    @end
    @implementation NSObject (Test)
     (NSString *) testFunction {
        return @"testFunction";
    }
    @end