Можно ли использовать в качестве селекторов не алфавитно-цифровые символы? - PullRequest
4 голосов
/ 14 июня 2011

Следующий код компилируется и работает нормально (обратите внимание на sel_registerName("+")):

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>

@interface Integer : NSObject
{
    NSInteger   intValue;
}

@property (assign) NSInteger intValue;

@end

@implementation Integer

@synthesize intValue;

- (id) plus:(Integer*)anInteger
{
    Integer* outInt = [Integer new];
    [outInt setIntValue: intValue + [anInteger intValue]];
    return outInt;
}

@end


int main (int argc, char const *argv[])
{
    id pool = [[NSAutoreleasePool alloc] init];

    SEL plusSel = sel_registerName("+");
    Method m = class_getInstanceMethod([Integer class], @selector(plus:));
    class_addMethod([Integer class], plusSel, method_getImplementation(m), method_getTypeEncoding(m));

    Integer* i4 = [Integer new];
    Integer* i20 = [Integer new];
    [i4 setIntValue: 4];
    [i20 setIntValue: 20];

    Integer* res = objc_msgSend(i4, plusSel, i20);

    NSLog(@"%d + %d = %d", [i4 intValue], [i20 intValue], [res intValue]);
    //  >> 4 + 20 = 24

    [pool drain];
    return 0;
}

Кроме «гадости», есть ли причины быть осторожными в этом?

Ответы [ 2 ]

1 голос
/ 14 июня 2011

API для среды выполнения ObjC вряд ли изменится, но допустимость вызова sel_registerName ("+") может измениться.Я много разбирался в среде выполнения ObjC и не столкнулся с какими-либо проблемами даже после многих обновлений.При этом я не буду основывать многомиллионный бизнес на том, что он будет работать вечно.

0 голосов
/ 25 марта 2013

В настоящее время библиотека времени выполнения Objective C не выполняет никаких проверок содержимого строки, которую вы пытаетесь зарегистрировать, и вряд ли команда разработчиков изменит это поведение.Если это непустая строка C, если вы всегда используете objc_msgSend для отправки сообщений для этого селектора, и если вы не пытаетесь сделать что-то вроде [i4 +:i20] (что приведет к ошибке компиляции), естьнет причин бояться.

Зарегистрированные селекторы Objective-C на самом деле являются строками C, хранящимися внутри системы времени выполнения.Система времени выполнения хранит таблицу указателей на строки C, так называемый набор SEL.Когда вы вызываете sel_registerName, система времени выполнения ObjC вызывает strcmp для вашей строки и для каждой строки C, хранящейся в наборе SEL.Если какая-либо из строк C в наборе SEL равна той, которую вы хотите зарегистрировать, функция возвращает адрес соответствующей строки C в наборе.В противном случае система дублирует вашу строку (с strdup), сохраняет результирующий указатель в наборе SEL и возвращает его.Этот новый указатель становится новым уникальным селектором.

...