Однако, когда я запускаю это, я получаю эту ошибку:
-[NSURL length]: unrecognized selector sent to instance 0x164dc0
Во-первых, это исключение , а не ошибка .
Когда вы получите такое сообщение, прочитайте, что оно говорит:
-[NSURL
Объект, которому вы отправили это сообщение, был объектом NSURL.
length]:
Селектор сообщения был length
.
Теперь, почему вы отправляете сообщение length
объекту NSURL? Вы бы не стали, и вы сами этого не сделали. Что-то еще сделал.
Но вы бы отправили сообщение length
объекту string . Итак, у вас есть объект NSURL, и вы передали его куда-то, где ожидалась строка.
В показанном вами коде есть только один отрывок:
[NSURL URLWithString:first]
Исключение говорит вам, что first
уже является NSURL; это не строка. Вам не нужно создавать NSURL из него, поскольку он уже один, и попытка обработать его как строку любым способом вызовет исключение.
Возможно, вы собираетесь возразить против моей претензии на основании этой предыдущей строки:
NSString *first = [urls objectAtIndex:[sender clickedRow]];
Ваше возражение состоит в том, что в декларации четко сказано, что first
является указателем на строку NSSt, поэтому я должен ошибаться.
Но это не так. Вы объявили first
как указатель на строку NSString. То есть вы сказали компилятору, что переменная first
будет содержать указатель на строку NSString.
Но затем вы помещаете указатель на NSURL в переменную.
Во многих случаях компилятор предупреждает вас, что вы обманули его, но в этом случае это не так, потому что объект прошел через objectAtIndex:
, что возвращает id
; таким образом, компилятор не знает, какой тип объекта вы помещаете в переменную. Компилятор, предполагая, что вы сказали правду и действительно помещаете здесь строку NSString, не предупреждает об этой инициализации.
Но это не так. Как вы узнали во время выполнения, объект является NSURL.
Исправление состоит из двух частей:
- Восстановите истину в объявлении, объявив переменную как
NSURL *
, а не NSString *
.
- Не пытайтесь создать NSURL здесь, потому что у вас уже есть.