Смущен использованием одной или нескольких звездочек в Objective-C - PullRequest
2 голосов
/ 30 мая 2011

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

- (BOOL)validateRadius:(id *)ioValue error:(NSError **)outError {
    NSLog(@"Validating radius using custom method");

    if ([*ioValue floatValue] < 7.0 || [*ioValue floatValue] > 10.0) { 
        // Fill out the error object 
        if (outError != NULL) {
            NSString *msg = @"Radius must be between 7.0 and 10.0";
            NSDictionary *dict = [NSDictionary dictionaryWithObject:msg forKey:NSLocalizedDescriptionKey];
            NSError *error = [[[NSError alloc] initWithDomain:@"Shapes" code:10 userInfo: dict] autorelease];
            *outError = error;
        }
        return NO;
    }
    return YES;
}

Меня смущают две вещи, и, поскольку я даже не знаю, как они технически называются, похоже, не могу найти в Google.

Первый - использование двойных звездочек ** в сигнатуре метода:

- (BOOL)validateRadius:(id *)ioValue error:(NSError **)outError {

Вторым является использование одной звездочки * при получении вызова метода:

[*ioValue floatValue]

Я не видел ни одной из этих двух вещей раньше, поэтому мне интересно, о чем они. Только что начал программировать на iOS 6 месяцев назад.

Любые объяснения или ссылки на онлайн-документацию приветствуются.

1 Ответ

3 голосов
/ 30 мая 2011

(id *)ioValue означает, что ioValue является указателем на идентификатор, а не на сам идентификатор. Выражение *ioValue относится к идентификатору, на который указывает ioValue.

(NSError **)outError означает, что outError является указателем на NSError * (который, в свою очередь, является указателем на NSError).

Обычная причина для передачи указателей на функции таким способом - позволить функции возвращать что-то вызывающей стороне.

В приведенном выше случае функция может присвоить новый id переменной, в которую передал вызывающий объект: *ioValue = something(). Однако, поскольку вышеприведенная функция фактически не делает этого, она кажется избыточной; он мог быть записан как (id)ioValue, а затем именоваться ioValue вместо *ioValue.

Однако, чехол outError имеет смысл. В случае ошибки функция создает объект ошибки (NSError *error = ...) и присваивает его переданной переменной таким образом: *outError = error. Это приводит к изменению исходной переменной, которую передал вызывающий объект, чтобы при возврате функции вызывающий мог проверить переменную и увидеть возникшую ошибку:

id ioValue = something();
IOError *err;
if ([foo validateRadius:&ioValue error:&err]) {
    NSLog("Yippee!");
} else {
    reportError(err);
}
...