Главная » iPhone, Objective-C, Программирование для iOS и MacOS » NSError Objective-C

0

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

Как говорилось в главе 9, если функция должна вернуть какую-либо информацию помимо своего возвращаемого значения, следует использовать механизм передачи по ссылке. Функции (или методу) передается ссылка на переменную, в которой сохраняется нужное значение или выполняются другие операции. Ссылка представляет собой адрес переменной в памяти. Для обработки ошибок многим методам передается по ссылке указатель на NSError. Включите обработку ошибок в приведенный выше пример:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {

@autore1easepoo1 {

NSMutableString *str = [[NSMutableString a11oc] init]; for (int i =0; i <10; i++) {

[str appendString:@"Aaron is coo1!\n"];

}

// 3десь указатель на объект NSError объявляется без создания

// экземпляра. 3кземпляр NSError будеr создан только при возникновении ошибки. NSError *еrror = nil;

// Передача по ссылке указателя NSError методу NSString B00L success = [str writeToFile:@"/tmp/cool.txt"

atomically:YES encoding:NSUTF8StringEncoding error:&error]:

// Проверка полученного флага и вывод информации из NSError в случае ошибки записи

if (succes) { } e1se {

NSLog(@"done writing/tmp/cool.txt");

}

NSLog(@"writing/tmp/cool.txt failed: %@", [еrror localizedDescription]);

}

return 0;

}

Постройте и запустите программу. Измените код таким образом, чтобы методу записи передавался несушествующий путь к файлу – например, @"/too/darned/ bad.txt". Программа должна вывести информативное сообщение об ошибке.

Обратите внимание: в этом коде мы объявляем указатель на экземпляр NSError,

но не создаем экземпляр NSError, который с этим указателем связывается.

Почему? Не стоит создавать объект ошибки, если ошибки не было. Если произойдет ошибка, то сообщение writeТoFile:atomically:encoding:еrror: обеспечит создание нового экземпляра NSError с последующим изменением указателя еrror, чтобы он указывал на созданный объект. Далее вы сможете по указателю еrror получить расширенную информацию об ошибке.

Условное создание NSError требует передачи ссылки на еrror (&error), потому

что объект, который можно было бы передать, еще не существует. Однако в отличие от передачи по ссылке, которая использовалась в главе 9 для примитивных переменных С, в данном случае передается адрес переменной-указателя. Фактически мы передаем адрес другого адреса (который может стать адресом объекта NSError).

Возвращаясь к нашему примеру со шпионами из главы 9, вы можете приказать своему подопечному: «Если что-то пойдет не так, составь полный отчет (который в тайнике не поместится) и заложи его в книгу в библиотеке. А чтобы я узнал, где спрятан отчет, положи в трубу библиотечный шифр книги». То есть вы сообщаете шпиону место, в котором он может спрятать адрес созданного им отчета об ошибке.

Заглянем вовнутрь класса NSString, в котором объявляется writeToFile: atomically:encoding:error::

-­‐   (BOOL)writeToFile:(NSString  *)path atomically:(BOOL)useAuxiliaryFile

encoding:(NSStringEncoding)enc error:(NSError **)error

Обратите внимание на двойную звездочку. При вызове этого метода мы передаем указатель на указатель на экземпляр NSError.

Методы, передающие NSError по ссылке, всегда возвращают значение, по которому можно определить, произошла ошибка или нет. Например, при наличии ошибки этот метод возвращает NO. Не пытайтесь обратиться к NSError, если возвращаемое значение не указывает на наличие ошибки; если объект NSError не существует, то попытка обращения к нему приведет к сбою программы.

Чтение файлов с использованием NSString Objective-C

Чтение содержимого файла в строку выполняется аналогичным образом:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])   {

@autoreleasepool {

NSError *error = nil;

NSString *str = [[NSString alloc] initWithContentsOfFile:@"/etc/ resolv.conf"

encoding:NSASCIIStringEncoding

if (!str) {

error:&error];

NSLog(@"read failed: %@", [error localizedDescription]);

} else {

NSLog(@"resolv.conf looks like this: %@", str);

}

}

return 0;

}

Источник: Аарон Хилегас, «Objective-C. Программирование для iOS и MacOS», 2012 г.

По теме:

  • Комментарии