В чем различие и варианты использования-ва списка, CVaListPointer, какой-либо объект ..., CVarArgType?
Вопрос
Может ли кто-нибудь объяснить различия между этими типами аргументов? Кроме того, если это возможно, пожалуйста, предоставьте соответствующие варианты использования с использованием кода (это стоит 1000 слов).Nota bene
Пожалуйста, дайте мне знать в комментариях, если есть какие-либо требования для получения дополнительной информации.
Фон
Я пытаюсь понять любые различия между следующими конструкциями и понять соответствующие примеры использования (с примерами, если таковые имеются). Я искал SO, Google, et, al. (блогосфера) не найдя удовлетворительного ответа.
При написании объекта хранилища данных я столкнулся со следующими инициализаторами для NSPredicate:
Заголовочный файл Swift (1.2) отмечает:
Комментарий блога указывает на следующее использование va_list в Objective-C
+ (void) log:(NSString *) format arguments:(va_list) argList
{
[self logString: [NSString stringWithFormat: format arguments:
argList]];
}
+ (void) log:(NSString *) format, ...
{
va_list argList;
va_start(argList, format);
{
[self log: format arguments: argList];
}
va_end(argList);
}
CVarArgType является протоколом и может использоваться следующим образом согласно Swift заголовочный файл.
В моем пользовательском классе у меня есть следующий вариант использования:
/* Finds an array of entity in the MOC if any exists using an optional
* predicate with an array of arguments
*
* Usage:
* eg. var items = CustomEntity.findInStore(dbStore, predicate:
* NSPredicate(format: "(attributeName IN %@)", argumentArray:
* ["value1","value2","value3"])) as? [CustomEntity]
*/
Редактировать:
Читатели обратите внимание, что параметр argumentArray был неправильно использован, как описано в моем пользовательском классе. Чтобы правильно использовать этот инициализатор, обратите внимание на следующее из документации Apple:
Что приводит меня к этому использованию:
NSPredicate(format: "(%K != %@ AND %K = %@)", argumentArray: ["key1","value1","key2","value2"])
1 ответ:
va_list
является типом C, используемым для функций переменных аргументов. Вы увидите это как параметр в коде Objective-C.
CVaListPointer
является эквивалентом swiftva_list
- везде, где вы видите функцию в Objective-C, которая принимаетva_list
в качестве аргумента, вы передадитеCVaListPointer
в Swift.objective-c: (NSPredicate *)predicateWithFormat:(NSString *)format arguments:(va_list)argList swift: init(format format: String, arguments argList: CVaListPointer) -> NSPredicate
CVarArgType
это протокол, который определяет, какие типы могут быть включены вCVaListPointer
, это включает в себя все примитивы (Int
,Float
,UInt
, и т.д.), а такжеCOpaquePointer
Функция полезности
withVaList
берет Swift-массив и преобразует его вCValListPointer
, который затем передается в обратный вызов. Обратите внимание, что передаваемый массив должен содержать только переменныеCVarArgType
:var format = "%@ != %@" var args: [CVarArgType] = ["abc", "def"] var s = withVaList(args) { (pointer: CVaListPointer) -> NSPredicate in return NSPredicate(format: format, arguments: pointer) }
Swift также определяет свой собственный варадический параметр
T...
, который должен быть последним параметром в функции, он передается в функцию как[T]
и используется таким образом.var arg1: String = "abc" var arg2: String = "def" NSPredicate(format: format, arg1, arg2)
Используйте встроенные в Swift параметры varadic
T...
везде, где это возможно.CValListPointer
следует использовать только тогда, когда вам нужно взаимодействовать с Objective C и C API, которые принимают аргументыva_list
.