В чем смысл паттерна Apple проверки возвращаемого значения, а не ошибки?

Решение этой проблемы только с одним открытым:

f = open("target.txt","r+")
d = f.readlines()
f.seek(0)
for i in d:
    if i != "line you want to remove...":
        f.write(i)
f.truncate()
f.close()

Это решение открывает файл в режиме r / w («r +») и использует поиск для сброса f-указателя, тогда truncate, чтобы удалить все после последней записи.

3
задан Andrey Chernukha 18 January 2019 в 10:37
поделиться

2 ответа

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

-(BOOL)sendCachedRequestReturningError: (NSError**)err {
    BOOL success = [self readCachedRequestReturningError:err];
    if (!success && (*err).domain == MYFileDomain && (*err).errorCode == MYFileNotFoundCode) {
        success = [self sendUncachedRequestReturningError:err];
    }

    return success;
}

Теперь здесь есть 4 пути кода:

  1. Существует кэшированный запрос. Мы просто вернемся success == YES и все хорошо.
  2. При попытке чтения из кэша возникает неисправимая ошибка. readCachedRequestReturningError: установит err и установит success == NO, и вызывающий абонент вызовет presentError: или что-то еще
  3. Произошла ошибка при попытке выполнить сетевой запрос. То же, что # 2, установлено err и success == NO.
  4. Кеша нет, но мы можем сделать сетевой запрос. readCachedRequestReturningError: установит err в допустимое значение NSError{MYFileDomain, MYFileNotFoundCode}, но затем sendUncachedRequestReturningError: выполнится успешно и установит success == YES, а не коснется err вообще, оставив в нем предыдущую ошибку. Если вы теперь проверяете err вместо проверки возвращаемого значения, вы будете думать, что произошла ошибка, когда все прошло хорошо.

Примечание: приведенный выше код сильно упрощен, потому что мы заботимся только об ошибках. Конечно, в реальной программе методы могли бы иметь другой возвращаемый параметр для фактического ответа на запрос или возвращать ответ или nil вместо success BOOL. Это также, вероятно, проверит, является ли err NULL. [Тысяча сто двадцать семь]

0
ответ дан uliwitness 18 January 2019 в 10:37
поделиться

Этот дизайн не очень необычный, сравните также ошибочно в стандартном C.

Дизайн имеет ряд потенциальных преимуществ:

  • Функция не должна писать через указатель на успех. Это не только делает реализацию таких функций более легкой и менее подверженной ошибкам, но также может быть небольшим преимуществом в производительности (например, это предотвращает аннулирование кэшей ЦП при успешном выполнении функции).

  • Если мы всегда проверяем, что функция не сработала, прежде чем получить доступ к ошибке, мы можем использовать один и тот же указатель ошибки для нескольких функций. В противном случае мы можем получить предыдущий сбой, а не сбой самой последней функции.

  • Это облегчает написание кода проверки. Например. функция может установить ошибку по умолчанию. Если все проверки пройдены, функция может просто вернуть успех вместо того, чтобы сбрасывать переменную ошибки.

  • Функция может использовать тот же указатель ошибки при вызове других функций, но сбой этих помощников не обязательно означает сбой верхней функции.

В вашем конкретном случае переменная NSError *theError; не была инициализирована. Доступ к этой переменной без ее назначения вначале вызовет неопределенное поведение. Документация только гарантирует, что переменная будет установлена ​​в случае ошибки.

0
ответ дан amon 18 January 2019 в 10:37
поделиться