2013-07-09 3 views
2

В моей модели реализации мне нужно иметь несколько разных файлов с некоторыми подобными методами. Кроме того, я собираю объекты типов Дифференц в NSMutableArray, и попытаться вызвать мой подобный метод, как это:Метод экземпляра не найден предупреждением, но работает

[[ArrayOfViews objectAtIndex:i] myMethodWithInt:'number' andExample:'char']; 

Но это дает мне предупреждение:

Instance method '...' not found (return type defaults to 'id') 

Мой код работает, но я должен исправить это предупреждение или нет?

+1

Вы всегда должны пытаться исправить предупреждения в C и базовых кодах Objective-C; они обычно указывают на серьезные (и часто фатальные) проблемы. – jlehr

+0

Вот почему я много работаю, чтобы обнаружить tand fix them =) – user2057209

ответ

2

Вы должны ввести тип:

MONType * obj = [ArrayOfViews objectAtIndex:i]; 

Затем вызвать метод с использованием типизированных переменной:

[obj myMethodWithInt:<#number#> andExample:<#char#>]; 

Это может быть жалуясь по целому ряду причин. Введение типа будет либо фиксировать эти категории проблем, либо, по крайней мере, дать вам более полезное предупреждение. В частности, компилятор не видит объявления метода экземпляра -myMethodWithInt:andExample:.

Возможно, вы либо не импортировали заголовок, либо объявили метод таким образом, чтобы он отображался в переводе.

Мой код работает, но должен ли я исправить это предупреждение или нет?

Возможно. Иногда это «работает». Это эквивалентно отсутствующим прототипам функций C89, которые были поэтапны из-за всех проблем, которые они вызвали. Таким образом, неявные параметры и возвращаемые типы могут работать, если параметры и тип возврата id совместимы (включая NSObject подклассы). Но если это не совпадение, вам следует ожидать неопределенного поведения. Вы можете избежать всего этого и ввести осмысленную проверку типов с помощью соответствующих импортов и деклараций в ваших программах и путем введения типа, как показано выше. Это полезно, потому что компилятор спасет вас от множества глупых ошибок при работе и по мере развития кодовых баз.

+0

Итак, как я могу определить тип элемента массива? Таким образом, объект принимает тип элемента массива (который является переменным) – user2057209

+0

@ user2057209 Во многих случаях вы можете использовать общую базу - например, если массив имеет только NSString и NSMutableStrings, и вам нужны только API NSString, вы можете просто использовать NSString в качестве общей базы. в противном случае вам нужно будет использовать динамическую проверку (например, '-isKindOfClass:'), которая может быть «вонючей». в некоторых случаях введение протокола может упростить этот процесс. логика с динамическими типами в коллекциях: «вы должны знать, что вы в нее вложили». – justin

+0

Элементы в массиве - все из разных файлов. Поэтому они все из разных классов. Массив должен содержать около ста элементов, поэтому было бы трудно проверить, выполняется ли '-isKindOfClass:': s У вас не могло быть такого процесса, как [ArrayOfViews objectAtIndex: 0] getClass]; (псевдо-код), чтобы заменить его? – user2057209

0

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

+0

Nop, потому что он находится в другом файле. Вот почему нормально не объявлять метод в основном файле. – user2057209

0

Добавление приведения к вызову objectAtIndex, чтобы избавиться от предупреждения. Это не большая проблема, но хорошей практикой является приведение типов результатов из NSArray.

В основном:

YourObjectType *yourObject = (YourObjectType*)[ArrayOfViews objectAtIndex:i]; 
[yourObject myMethodWithInt:'number' andExample:'char']; 
+0

([[ArrayOfViews objectAtIndex: 0] class] *) [ArrayOfViews objectAtIndex: 0] для замены (YourObjectType *) [ArrayOfViews objectAtIndex: i] не должен работать? – user2057209

+0

:) Ну, это интересная вещь, чтобы попробовать, но нет, я думаю, что это приводит к ошибке компилятора.Как я вижу это, если вы знаете сигнатуру метода для объекта, вы также должны знать тип объекта. – Sid

+0

Вы согласны с тем, что это не работает:/Я не мог просто добавить бросок, когда вы в первый раз добавляете больше, чем создать новый объект? Поскольку все объекты в массиве имеют разные типы объектов, и поэтому я использую массив:/ – user2057209

0

Вы должны добавить #import заявление для заголовка, который объявляет метод или методы, которые вы хотите позвонить.

+0

Извините, что код работает. Будет ошибка выполнения, если он забудет оператор #import. – Sid

+1

Сид прав. У меня уже есть оператор '# import'. – user2057209

+0

@Sid Пожалуйста, объясните, как отсутствие объявления времени компиляции может вызвать ошибку времени выполнения. – jlehr

Смежные вопросы