Значение аргумента Objective-C по умолчанию - PullRequest
14 голосов
/ 16 мая 2009

Привет, быстрый вопрос здесь. Я уверен, что есть простой ответ.

Исходя из PHP, я привык объявлять функцию со значением аргумента по умолчанию, например:

function myFunction ($array, $sort = FALSE)  {

}

Если параметр сортировки не был заполнен, функция продолжит работу со значением по умолчанию, равным false. В Obj-C есть похожая вещь?

Я работаю над упражнениями из моей книги «Программирование в Objective-C 2.0» и хочет, чтобы я переписал функцию печати класса дроби, чтобы по умолчанию не уменьшать дробь, но если значение TRUE дается уменьшение, продолжайте и уменьшите дробь, затем напечатайте. Глава (нигде в книге) не дает никакой информации об этом.

Спасибо за вашу помощь, ребята: D

Ответы [ 6 ]

25 голосов
/ 16 мая 2009

По умолчанию в Objective-C отсутствуют аргументы по умолчанию. Они не могут на самом деле, потому что количество аргументов неразрывно связано с именем метода - каждое двоеточие соответствует одному аргументу.

Программисты Objective-C достигают аналогичной цели, создавая «удобные» методы, которые просто вызывают более «примитивный» метод с некоторыми аргументами, заполненными значениями по умолчанию. Например, -[NSArray indexOfObject:] может быть реализовано как версия -[NSArray indexOfObject:inRange:] с аргументом NSMakeRange(0, [self count]) для части inRange:.

В этом случае, однако, я не думаю, что ваша книга говорит об этом. Я думаю, что это просто означает уменьшить долю, если ДА дано для аргумента reduce:, и не уменьшить его, если ДА дано.

10 голосов
/ 16 мая 2009

Есть два стандартных шаблона для достижения того, что вы хотите.

(1) написать метод с множеством аргументов и затем предоставить меньше удобных версий аргументов. Например, рассмотрим следующие методы NSString:

- (NSComparisonResult)compare:(NSString *)string;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask
            range:(NSRange)compareRange;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask
            range:(NSRange)compareRange locale:(id)locale;

Первые три концептуально [и, вероятно, конкретно, я не проверял] реализованы как обращения к четвертой версии. Это -compare: вызывает -compare: параметры: диапазон: локаль: с соответствующими значениями по умолчанию для трех дополнительных аргументов.

(2) Другой шаблон заключается в реализации версии метода с несколькими аргументами и предоставлении значений по умолчанию, когда аргумент равен NULL / nil или установлен на некоторое значение, которое указывает, что по умолчанию требуется. NSData имеет методы, которые реализованы с этим шаблоном. Например:

+ (id)dataWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)readOptionsMask
            error:(NSError **)errorPtr;

Если вы передадите 0 в качестве аргумента readOptionsMask, NSData прочитает содержимое файла, используя внутреннюю конфигурацию по умолчанию. Эта конфигурация по умолчанию может меняться со временем.

8 голосов
/ 14 декабря 2010

Этот вопрос очень старый, но в случае, если кто-нибудь найдет его, версия PHP-кода Objective-C (при условии, что он находится внутри класса), вероятно, будет выглядеть примерно так:

-(id)myFunction:(NSArray*)array {
  return [self myFunction:array withSort:FALSE];
}

-(id)myFunction:(NSArray*)array withSort:(BOOL)useSort {
   // CODE
}

Я использовал (id) s, поскольку в вашем PHP-коде нет информации о типе данных. Было бы разумно заменить (id) фактическими типами данных.

4 голосов
/ 30 января 2013

Ужасный некро, но для любого, кто гуглит это, Xcode 4.5 поддерживает (через Clang ) перегрузку функций C с помощью __attribute__((overloadable)).

Перегруженные функции могут иметь разное количество аргументов, поэтому, если функции C подходят для того, что вы пытаетесь сделать, вы можете использовать это для получения значений аргументов по умолчанию.

Вот надуманный пример файла .h с двумя функциями, каждая из которых называется PrintNum:

// Prints a number in the decimal base
__attribute__((overloadable)) extern void PrintNum(NSNumber *number);

// Prints a number in the specified base
__attribute__((overloadable)) extern void PrintNum(NSNumber *number, NSUInteger base);

и в файле .m:

__attribute__((overloadable)) 
void PrintNum(NSNumber *number) {
    PrintNum(number, 10);
}

__attribute__((overloadable))
void PrintNum(NSNumber *number, NSUInteger base) {
    // ...
}

Обратите внимание, что атрибут должен быть указан во всех определениях и объявлениях функции.

1 голос
/ 16 мая 2009

Нет, аргументы по умолчанию являются функцией C ++, а не C или Objective-C.

То, что вам нужно сделать в target-c, - это следующее (используя код psuedo выше):

function myFunction ($array, $sort)

function myFunction ($array)
// call myFunction($array, FALSE)
0 голосов
/ 09 сентября 2015

Вы можете легко добиться того же эффекта, используя #define.

Функция в вашем заголовочном файле:

+(NSDate*)getDateFromYear:(NSUInteger)year month:(NSUInteger)month day:(NSUInteger)day;

Добавить #define для функции параметра в заголовочный файл:

#define GetDateFromYearOnly(year) [YourClassName getDateFromYear:year month:1 day:1]

Тогда вы можете использовать функцию как:

NSDate* 2015Date = GetDateFromYearOnly(2015);

И вы получите NSDate объект с датой 2015/01 / 01.

Если функция не static, создайте новую функцию следующим образом:

-(NSDate*)GetDateFromYearOnly:(NSUInteger)year;

И звоните:

[self getDateFromYear:year month:1 day:1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...