Подавление “'…' удерживается от использования” при использовании respondsToSelector

Для простых случаев Вы можете Вы Ваш метод стиля переключателя. Что я нашел, что работы хорошо в прошлом должны иметь дело с переходами также:

static int current_state;    // should always hold current state -- and probably be an enum or something

void state_leave(int new_state) {
    // do processing on what it means to enter the new state
    // which might be dependent on the current state
}

void state_enter(int new_state) {
    // do processing on what is means to leave the current atate
    // might be dependent on the new state

    current_state = new_state;
}

void state_process() {
    // switch statement to handle current state
}

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

56
задан s4y 14 December 2009 в 22:14
поделиться

5 ответов

Я нашел пример в руководстве пользователя компилятора Clang, который позволяет мне игнорировать предупреждение:

if ([fileManager respondsToSelector:@selector(removeItemAtPath:error:)]) {
    [fileManager removeItemAtPath:downloadDir error:NULL];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    [fileManager removeFileAtPath:downloadDir handler:nil];
#pragma clang diagnostic pop
}
116
ответ дан 26 November 2019 в 17:11
поделиться

Вы можете объявить отдельный файл, предназначенный для вызова устаревших методов, и установить флаги компилятора для каждого файла в Xcode, чтобы игнорировать -Wdeprecated-declrations . Затем вы можете определить фиктивную функцию в этом файле для вызова устаревших методов и тем самым избежать предупреждений в ваших реальных исходных файлах.

8
ответ дан 26 November 2019 в 17:11
поделиться

Если вы считаете любую форму "запутывания" компилятора недопустимым решением, вам, вероятно, придется жить с предупреждением. (В моей книге, если вы спрашиваете, как избавиться от предупреждения, неразумно смотреть дареному коню в рот и говорить что-то недействительное только потому, что это выглядит не так, как вы ожидаете.)

Ответы эта работа во время выполнения включает маскирование операции, которая происходит с динамической отправкой, чтобы компилятор не жаловался на устаревший вызов. Если вам не нравится такой подход, вы можете отключить «Предупреждать об устаревших функциях» в своем проекте Xcode или целевых настройках, но это, как правило, плохая идея. Вы хотите знать об устаревших API, но в этом случае вы хотите использовать его без предупреждения. Есть простой и трудный способы сделать это, и есть вероятность, что вы сочтете все из них «недействительными» в той или иной форме, но это не мешает им быть эффективными, даже правильными. ; -)

Один из возможных способов избежать предупреждений, но все же выбрать во время выполнения, - это использовать objc_msgSend () напрямую:

objc_msgSend(fileManager, @selector(removeFileAtPath:error:), downloadDir, nil];

Это то, что среда выполнения Objective-C в любом случае делает под прикрытием и должен достичь желаемого результата с минимумом хлопот. Вы даже можете оставить комментарий над исходной строкой для ясности. Я знаю, что в документации говорится: «Компилятор генерирует вызовы функции обмена сообщениями. Вы никогда не должны вызывать ее непосредственно в коде, который вы пишете». Вы сами должны решить, когда можно нарушить правила.

t мешают им быть эффективными, даже правильными. ; -)

Один из возможных способов избежать предупреждений, но все же выбрать во время выполнения, - это использовать objc_msgSend () напрямую:

objc_msgSend(fileManager, @selector(removeFileAtPath:error:), downloadDir, nil];

Это то, что среда выполнения Objective-C в любом случае делает под прикрытием и должен достичь желаемого результата с минимумом хлопот. Вы даже можете оставить комментарий над исходной строкой для ясности. Я знаю, что в документации говорится: «Компилятор генерирует вызовы функции обмена сообщениями. Вы никогда не должны вызывать ее непосредственно в коде, который вы пишете». Вы сами должны решить, когда можно нарушить правила.

t мешают им быть эффективными, даже правильными. ; -)

Один из возможных способов избежать предупреждений, но все же выбрать во время выполнения, - это использовать objc_msgSend () напрямую:

objc_msgSend(fileManager, @selector(removeFileAtPath:error:), downloadDir, nil];

Это то, что среда выполнения Objective-C в любом случае делает под прикрытием и должен достичь желаемого результата с минимумом хлопот. Вы даже можете оставить комментарий над исходной строкой для ясности. Я знаю, что в документации говорится: «Компилятор генерирует вызовы функции обмена сообщениями. Вы никогда не должны вызывать ее непосредственно в коде, который вы пишете». Вы сами должны решить, когда можно нарушить правила.

objc_msgSend(fileManager, @selector(removeFileAtPath:error:), downloadDir, nil];

Это то, что среда выполнения Objective-C в любом случае делает под прикрытием , и она должна достичь желаемого результата с минимумом хлопот. Вы даже можете оставить комментарий над исходной строкой для ясности. Я знаю, что в документации говорится: «Компилятор генерирует вызовы функции обмена сообщениями. Вы никогда не должны вызывать ее непосредственно в коде, который вы пишете». Вы сами должны решить, когда можно нарушить правила.

objc_msgSend(fileManager, @selector(removeFileAtPath:error:), downloadDir, nil];

Это то, что среда выполнения Objective-C в любом случае делает под прикрытием , и она должна достичь желаемого результата с минимумом хлопот. Вы даже можете оставить комментарий над исходной строкой для ясности. Я знаю, что в документации говорится: «Компилятор генерирует вызовы функции обмена сообщениями. Вы никогда не должны вызывать ее непосредственно в коде, который вы пишете». Вы сами должны решить, когда можно нарушить правила.

3
ответ дан 26 November 2019 в 17:11
поделиться

doCompare должен быть static . Если doCompare требуются данные из MyClass , вы можете превратить MyClass в функтор сравнения, изменив:

doCompare( const int & i1, const int & i2 ) { // use some member variables } 

на

bool operator () ( const int & i1, const int & i2 ) { // use some member variables } 

и вызвав:

doSort() { std::sort(arr,arr+someSize, *this); }

Также, Разве doSort не пропускает возвращаемое значение?

Думаю, можно использовать std :: mem_fun и какую-то привязку, чтобы превратить функцию-член в бесплатную функцию , но точный синтаксис в данный момент ускользает от меня.

EDIT: Doh, std :: sort принимает функтор по значению, что может быть проблемой.

6
ответ дан 26 November 2019 в 17:11
поделиться

Вы можете просто преобразовать fileManager в id - id могут ссылаться на любой объект Objective-C, поэтому компилятор не должен проверять методы, которые вызываются для одного:

[(id)fileManager removeItemAtPath:downloadDir error:NULL];

не должен вызывать никаких предупреждений или ошибок.

Конечно, это вызывает другие проблемы, а именно, вы теряете все проверка во время компиляции для методов, вызываемых по идентификатору id . Поэтому, если вы неправильно написали имя метода и т. Д., Оно не будет обнаружено, пока эта строка кода не будет выполнена.

5
ответ дан 26 November 2019 в 17:11
поделиться