Nice programing

respondsToSelector를 사용할 때 " '…'는 더 이상 사용되지 않음"표시 안 함

nicepro 2020. 12. 28. 22:32
반응형

respondsToSelector를 사용할 때 " '…'는 더 이상 사용되지 않음"표시 안 함


런타임에 최신 API를 선택하여 10.4 이상을 지원하고 있습니다.

if ([fileManager respondsToSelector:@selector(removeItemAtPath:error:)])
    [fileManager removeItemAtPath:downloadDir error:NULL];
else
    [fileManager removeFileAtPath:downloadDir handler:nil];

이 경우 10.5 이상은를 사용 removeItemAtPath:error:하고 10.4는 removeFileAtPath:handler:. 훌륭하지만 이전 메서드에 대한 컴파일러 경고가 계속 표시됩니다.

warning: 'removeFileAtPath:handler:' is deprecated [-Wdeprecated-declarations]

if([… respondsToSelector:@selector(…)]){ … } else { … }컴파일러 (Clang)가 해당 줄에서 경고하지 않도록 힌트 하는 구문이 있습니까?

그렇지 않은 경우 무시할 해당 줄에 태그를 지정하는 방법이 -Wdeprecated-declarations있습니까?


몇 가지 답변을 본 후 컴파일러를 혼란스럽게하여 내가하는 일을 알지 못하는 것은 유효한 해결책이 아님을 분명히하겠습니다.


Clang Compiler User 's Manual에서 경고를 무시할 수 있는 예제찾았습니다 .

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
}

더 이상 사용되지 않는 메서드를 호출하도록 지정된 별도의 파일을 선언하고 Xcode에서 파일 별 컴파일러 플래그를 무시하도록 설정할 수 -Wdeprecated-declarations있습니다. 그런 다음 해당 파일에 더미 함수를 정의하여 더 이상 사용되지 않는 메서드를 호출하여 실제 소스 파일에서 경고를 피할 수 있습니다.


clang이 이것을 잡을만큼 똑똑한 지 확실하지 않지만 그렇지 않다면 performSelector:withObject:withObject:NSInvocation 객체를 사용 하거나 빌드하고 호출 할 수 있습니다.


당신이 바로 캐스팅 할 수 fileManagerid- ids컴파일러는 하나라고 방법을 확인 안되도록, 어떤 목표 - C 객체를 참조 할 수 있습니다 :

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

경고 나 오류를 발생 시키지 않아야 합니다.

물론 이로 인해 다른 문제가 발생합니다. 즉,에서 호출 된 메서드에 대한 모든 컴파일 타임 검사를 잃게됩니다 id. 따라서 메서드 이름 등의 철자를 잘못 입력하면 해당 코드 줄이 실행될 때까지 포착되지 않습니다.


컴파일러를 "혼란"하는 어떤 형태 든 잘못된 솔루션이라고 생각한다면 경고와 함께 살아야 할 것입니다. (내 책에서 경고를 없애는 방법을 묻는다면 선물 말을 입에 넣고 예상 한 것처럼 보이지 않는다고해서 무언가 잘못되었다고 말하는 것은 현명하지 않습니다.)

런타임에 작동하는 대답은 컴파일러가 더 이상 사용되지 않는 호출에 대해 불평하지 않도록 동적 디스패치로 발생하는 작업을 마스킹하는 것입니다. 이러한 접근 방식이 마음에 들지 않으면 Xcode 프로젝트 또는 대상 설정에서 "Warn About Deprecated Functions"를 끌 수 있지만 이는 일반적으로 나쁜 생각입니다. 더 이상 사용되지 않는 API에 대해 알고 싶지만이 경우 경고없이 사용하려고합니다. 이 작업을 수행하는 쉽고 어려운 방법이 있으며, 어떤 형태로든 모두 "잘못된"것으로 간주 할 가능성이 있지만 그렇다고해서 효과가 있고 정확하지도 않습니다. ;-)

경고를 피하면서도 런타임에 선택하는 한 가지 가능한 방법은 objc_msgSend()직접 사용 하는 것입니다.

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

이것은 Objective-C 런타임이 어쨌든 내부적으로 수행하는 작업이며 최소한의 소란으로 원하는 결과를 달성해야합니다. 명확성을 위해 원래 줄을 그 위에 주석으로 남겨 둘 수도 있습니다. 문서에서 "컴파일러는 메시징 함수에 대한 호출을 생성합니다. 작성한 코드에서 직접 호출해서는 안됩니다." 규칙을 구부리는 것이 언제 괜찮을지 결정해야합니다.

참조 URL : https://stackoverflow.com/questions/1902021/suppressing-is-deprecated-when-using-respondstoselector

반응형