Как я могу проверить на int в списке variadic? - PullRequest
2 голосов
/ 23 сентября 2011

У меня есть метод, который может принимать переменное количество аргументов.

Я использую команды с переменным числом аргументов, чтобы получить аргументы и сохранить их в NSMutableDictionary.

Проблема в том, что, если я посылаю int в метод, я получаю сбой, потому что NSMutableDictionaries можетне хранить int.

Что я хочу сделать, так это заставить метод проверить, является ли один из аргументов целым числом, и, если это так, превратить его в номер NSNumber, прежде чем помещать его в словарь.

Но я не могу на всю жизнь выяснить, как проверить int.

[Я знаю, что один ответ будет "не отправляйте int в метод, только отправляйтеNSNumbers!»Проблема заключается в том, что на вызывающего метода накладывается обязательство, которое не может быть определено только из описания метода.]

Ответы [ 3 ]

3 голосов
/ 23 сентября 2011

Я недавно натолкнулся на концепцию «Типовые кодировки» в Apple doc. Это делается с использованием директивы компилятора @ encode () . Док говорит, что "Если задана спецификация типа, @encode () возвращает строку, кодирующую этот тип" .

Итак, пойте @ encode () и typeof () и strcmp () мы можем найти тип передаваемой переменной. typeof () возвращает тип переменной. Например, @ encode (int) возвращает "i" и рассматривает переменную с именем var как целочисленную переменную, тогда typeof (var) вернет int . В этом случае @ encode (int) и @ encode (typeof (var)) вернет только "i" . Мы можем проверить равенство строк, используя метод strcmp () .

if (strcmp(@encode(typeof(variable)), @encode(int)) == 0) {

    // The varibale is an "int"
    // @encode(int) returns "i"

    // @encode(float) returns "f"
    // @encode(double) returns "d"

} else if (strcmp(@encode(typeof(variable)), @encode(NSObject *)) == 0) {

    // The varibale is an "object"
    // @encode(NSObject *) returns "@"
    // You can use anything in the place of NSObject in the above line
    // @encode(NSString *) or @encode(UIButton *) will also return "@"
}

Для всех кодировок типов Objective C существует список. Вы можете проверить кодировки строк других типов в приведенной выше ссылке Apple Doc.

Применение вышеупомянутой концепции в функциях с переменными числами: Будет почти невозможно использовать вышеуказанную концепцию кодирования типов для переменных с переменными типами, поскольку мы получаем каждый аргумент из метода va_arg () только после указания типа в качестве аргумента. Итак, мы пытаемся получить аргумент для поиска его типа из метода va_arg (), который сам требует, чтобы тип возвращал аргумент. Немного раздражает!

3 голосов
/ 23 сентября 2011

Тип аргументов в списках переменных не может быть проверен. Он должен быть указан другим способом.

Например, NSLog() использует аргумент формата для получения информации о типе: %@ для объекта, %d для целочисленного значения или %f для значения с плавающей запятой.

1 голос
/ 26 сентября 2011

Редактировать: это не работает. Я думал, что это так, но сейчас я получаю сбои, я не понимаю. Если я это выясню, я приду редактировать это больше. Вот что я написал раньше, что неправильно. Опять же, это не работает:

Я думаю, что нашел ответ на этот вопрос: Кодирование значения ключа.

С помощью Key-Value Coding я могу установить переменную экземпляра типа id, а затем динамически идентифицировать фактическое содержимое переменной. я может положить что-нибудь в него, даже int, и методы Key-Value определить это для меня. Но что еще удивительнее, если я получить содержимое переменной, используя Key-Value Coding, и переменная оказывается int, кодирование значения ключа автоматически превращается это в NSNumber для меня.

Я попытаюсь продемонстрировать.

Главное - установить операторы доступа для переменной I хочу получить доступ. Итак, для этого примера, скажем, переменная называется "IdentifMe."

//in the interface:
@property (copy) id accessIdentifyMe;

//in the implementation:
@synthesize accessIdentifyMe = identifyMe;

Теперь «identifMe» соответствует значениям ключа. Мы в порядке.

Все, что мне нужно сделать, это взять предметы из списка вариадик, передать их в IdentifMe один за другим, и использовать методы Key-Value для определения содержание. Вот так:

/*...assume all the following is happening inside a loop that

считает через Вариационный список. Я назову список вариантов "variadicList". Во-первых, я беру текущий элемент переменной и поместите его в IdentifMe, объявив его как тип "Я бы"*/ identifMe = va_arg (variadicList, id);

/*Now I use a Key-Value method to check if identifyMe holds an

NSNumber. Если оно содержит int, он будет автоматически возвращен как NSNumber, вы помните, так запрос для NSNumber функционально такой же, как запрос для int.
Вне цикла я установил удобное логическое значение с именем foundANumber в котором сохранить результаты запроса: * / foundANumber = [[self valueForKey: @ "identifMe"] isKindOfClass: [NSNumber class]];

Это дало мне возможность отделить числа от объектов. После этого я могу поместить объекты непосредственно в свой словарь и поместите числа в NSNumber прежде, чем я поместу их в словарь.

И что это означает на другом конце, когда вызывается этот метод из другой объект, это то, что я могу вызвать этот метод и поместить int в список параметров и не беспокоиться о возникновении сбоя. Yay.

Вот причина, по которой это не работает: KVC не волшебство. Я думал, что у него есть какой-то супер особый способ определения типа переменной, но это не так. Он просто смотрит на тип, объявленный в методах доступа, и не может независимо проверить больше. Штопать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...