Использование #pragma для подавления предупреждений «Метод экземпляра не найден» в XCode - PullRequest
6 голосов
/ 16 февраля 2012

Я хочу использовать #pragma (в Xcode) для подавления предупреждения:

предупреждение: метод экземпляра '-someMethod' не найден (тип возвращаемого значения по умолчанию равен 'id')

Я пробовал:

#pragma GCC diagnostic ignored "-Wmissing-declarations"

И несколько других, но ничего не работает.

Какое предупреждение вызывает "метод экземпляра не найден"?

Редактировать

В соответствии с запросом, здесь указан фактический код:

...

if (sampleRate > 0 && ![self isFinishing])  //<--- Warning here
{
    return self.progress;
}

...

И вывод журнала сборки:

/Users/User1/Documents/Project/branch/client/Folder/CodeFile.m:26:32:{26:32-26:50}: warning: instance method '-isFinishing' not    found (return type defaults to 'id') [3]
     if (sampleRate > 0 && ![self isFinishing])
                            ^~~~~~~~~~~~~~~~~~

Ответы [ 5 ]

9 голосов
/ 22 февраля 2012

См .: https://stackoverflow.com/a/34043306/89035 для #pragma для подавления предупреждений "метод экземпляра не найден".

Хотя кажется, что истинное #pragma решение этой проблемы делаетне существует отключение предупреждений в отдельных файлах может быть выполнено с помощью переключателя -w.

NB: Это решение для Xcode 4.2 и выше

  1. Выберите цель
  2. Нажмите на вкладку «Этапы сборки»
  3. В разделе «Исходники компиляции» добавьте переключатель -w к нужному файлу (файлам)подавить предупреждения на

Xcode - compile sources - suppress warnings

4 голосов
/ 02 декабря 2015

Какое предупреждение вызывает "метод экземпляра не найден"?

Это -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 (компилятор не будет создавать никаких код для проверки во время выполнения, он доверяет вашему слову!)

3 голосов
/ 21 февраля 2012

ОК, я снова :) Я пробовал различные специфичные для clang #pragma s, но ничего не получалось, и единственное, о чем я мог подумать, - это объявить метод как "закрытый метод" внутри класса, который на самом деле использует метод, таким образом:

main.m:

#import <Foundation/Foundation.h>
#import "PragmaTest.h"

@interface PragmaTest ()

    - (void)noSuchMethod;

@end


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

    @autoreleasepool {

        PragmaTest *pragmaTest = [[PragmaTest alloc] init];

        #pragma clang diagnostic push
        #pragma clang diagnostic ignored "-Wall"

        [pragmaTest noSuchMethod];

        #pragma clang diagnostic pop

        [pragmaTest release];

        // insert code here...
        NSLog(@"Hello, World!");

    }
    return 0;
}

PragmaTest.h:

#import <Foundation/Foundation.h>

@interface PragmaTest : NSObject

@end

PragmaTest.m:

#import "PragmaTest.h"

@implementation PragmaTest

- (void)noSuchMethod
{
    NSLog(@"noSuchMethod");
}

@end

Я надеюсь, что это соответствует вашим требованиям, и, хотя это не решение, включающее #pragma s, я надеюсь, что вы не почувствуете необходимости понизить полезный ответ.

1 голос
/ 05 марта 2018

Вот как вы можете подавить предупреждения. Это особенно полезно в тестовых (поддельных) классах, где вы хотите реализовать только несколько методов класса, а остальные не нужны.

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"

@implementation MyClass


@end

#pragma clang diagnostic pop
1 голос
/ 21 февраля 2012

Ссылка Павана хороша, но может быть и более простой ответ. Ваш метод isFinishing находится в вашем файле .m, но объявлен ли после его использования (где вы получаете предупреждение)? Если это так, переместите декларацию перед ее использованием. Если этот простой случай не тот ответ, который вам нужен, вы можете использовать категорию, чтобы сообщить компилятору об этом методе. Я часто делаю это для модульного тестирования "частных" методов. Другой вариант - использовать флаг компилятора для этого файла, чтобы отключить это предупреждение для всего файла. Я знаю, что ни один из них не указывает, как решить эту проблему с помощью прагмы, но вы можете найти другое жизнеспособное решение.

...