Какое предупреждение вызывает "метод экземпляра не найден"?
Это -Wobjc-method-access
, поэтому попробуйте
#pragma GCC diagnostic ignored "-Wobjc-method-access"
или скомпилируйте этот файл с помощью -Wno-objc-method-access
, чтобы только подавить это предупреждение.
Оба решения выше имеют ограничение, что они будут применяться ко всему файлу, что обычно не то, что вы хотите. clang
предлагает вам еще лучшую альтернативу:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
if (sampleRate > 0 && ![self isFinishing])
{
return self.progress;
}
#pragma clang diagnostic pop
Первая прагма сохраняет все текущие флаги предупреждений во внутренний стек, затем вы устанавливаете это одно предупреждение как игнорируемое для кода, который будет следовать, и после этого кода в последней строке будет отображаться сохраненное состояние и, таким образом, снова восстанавливаются все флаги предупреждений. .
Обратите внимание, что тот факт, что вы получаете такое предупреждение, означает, что в вашем коде есть что-то подозрительное. Либо этот метод на самом деле не существует, в этом случае вам не следует его вызывать, или он будет существовать во время выполнения, вы просто забыли сообщить об этом компилятору.
Сначала вы должны сделать свой код безопасным, потому что вызов несуществующего метода обычно приводит к сбою приложения:
if (sampleRate > 0
&& ([self respondsToSelector:@selector(isFinishing)]
&& ![self isFinishing]
)
) {
return self.progress;
}
Этот код сначала проверяет, является ли вызов isFinishing
нормальным или скорее фатальным. Только если все в порядке, вызов фактически выполняется.
Теперь компилятору все еще нужно знать о методе isFinishing
, не только о том, что он существует, но и о том, что он возвращает. Машинный код для ![self isFinishing]
не обязательно должен быть одинаковым для метода, возвращающего bool, возвращающего целое число, возвращающего double или возвращающего объект (или любой другой тип указателя). Компилятор может генерировать правильный код, только если ему известен прототип этого метода. Самый простой способ - использовать для этого свойство. Вы можете объявить это свойство в вашем исходном файле (файл .m), если вы не хотите показывать его в своем файле заголовка (файл .h), просто объявите его в расширении класса (это в основном безымянная категория):
@interface YourClass ( )
@property (readonly) BOOL isFinishing;
@end
@implementation YourClass
// Implementation of the class follows here
Теперь компилятор знает, что isFinishing
возвращает BOOL
. И чтобы избежать того, что компилятор генерирует какой-либо код для этого свойства, вы помещаете это в реализацию:
@dynamic isFinishing;
Это говорит компилятору ничего не делать для этого свойства (не создавать ivar, не создавать getter) и просто предполагать, что во время выполнения будет существовать метод с именем isFinishing
(компилятор не будет создавать никаких код для проверки во время выполнения, он доверяет вашему слову!)