Loại bỏ các cảnh báo không dùng nữa trong Xcode


133

Với tất cả các SDK nổi xung quanh, thật tiện dụng để có thể xây dựng cho nhiều SDK và nền tảng. Tuy nhiên, nảy từ 3.2 đến 3.0 và thậm chí đôi khi 2.x, tôi thường xuyên nhận được các cảnh báo không dùng nữa liên quan đến các phương pháp đã thay đổi hoặc được thay thế:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

Vì tôi vẫn muốn duy trì khả năng tương thích với các hệ điều hành cũ hơn và tôi cũng đang cố gắng loại bỏ 'tiếng ồn' khi xây dựng, có cách nào để tắt hoặc tắt các cảnh báo này không?


4
Trong khi câu trả lời của Paul R hoạt động, hãy xem xét rằng manicaesar là một phẫu thuật hơn một chút, ở chỗ nó cho phép bạn loại bỏ chính xác cảnh báo bạn muốn, mà không mất các cảnh báo bổ sung khác có thể quan trọng. Dường như với tôi, về mặt thực hành tốt nhất, manicaesar có Câu trả lời đúng ™
Olie

Câu trả lời:


82

Hãy thử -Wno-deprecated-declarationshoặc cài đặt tương ứng của nó trong Xcode, GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS(mẹo chuyên nghiệp: chỉ cần nhập "không dùng nữa" trong cài đặt bản dựng để tìm cài đặt cụ thể cho cảnh báo này).

Các phiên bản hiện tại của Xcode (ví dụ Xcode 9.2):

nhập mô tả hình ảnh ở đây


Các phiên bản cổ của Xcode (ví dụ Xcode 2.x, 3.x):

nhập mô tả hình ảnh ở đây


17
Hóa ra nó còn dễ hơn thế nữa; có một hộp kiểm trong cài đặt mục tiêu Xcode; câu trả lời của bạn nhắc tôi tìm kiếm ở đó. Cảm ơn!
Ben Gottlieb

4
Bạn cũng có thể làm điều này trên cơ sở mỗi tệp. Xem câu trả lời này để thêm cờ cho mỗi tệp: stackoverflow.com/a/6658549/272473
mrwalker

4
câu trả lời như thế này là bực bội cho newbs. Dùng thử ở đâu? Làm cách nào để tìm cài đặt mục tiêu? Giải thích thêm một chút sẽ làm tăng giá trị của câu trả lời này.
noogrub

8
Một câu trả lời được giải thích kém này không nên được đánh dấu là chính xác.
Chris Hatton

6
Tìm kiếm "Không dùng nữa" trong cài đặt bản dựng và bạn sẽ thấy nó.
quantumpotato

337

Vì tôi chưa thể thêm nhận xét vào bài đăng @samiq, tôi nghĩ rằng tôi sẽ mở rộng nó. Nhập lệnh được đề cập trước một hàm / phương thức mà bạn sử dụng nội dung không dùng nữa. Sau đó, bạn có thể khôi phục cài đặt trước đó sau khi định nghĩa của hàm kết thúc:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma GCC diagnostic pop

1
Thông minh! Đây là những gì tôi đang tìm kiếm +1 :)
Zoran Simic

1
Mẹo tuyệt vời! Quá tệ, nó không thể được khai báo bên trong một phương thức.
Dustin

12
Trên thực tế nó có thể được khai báo bên trong một phương thức. Tôi vừa phải làm điều đó hôm nay do một lỗi trong tài liệu / sdk
jer

6
+1 Cách tốt hơn một chút là sử dụng cú pháp #pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. Code here .. .. #pragma GCC diagnostic pop vì phương thức này sẽ đưa bạn trở lại bất kỳ cài đặt nào đã được đặt trước đó .. [ gcc.gnu.org/onlinesocs/gcc/Diagnellect-Pragmas.html]
Niclas

3
Thay đổi từ gợi ý :)
manicaesar

143

Clang cung cấp một tính năng hay làm cho bước "khôi phục" trong bài đăng @manicaesar độc lập với trạng thái cảnh báo ban đầu:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop

Để trích dẫn hướng dẫn sử dụng Clang :

Ngoài tất cả các chức năng được cung cấp bởi pragma của GCC, Clang cũng cho phép bạn đẩy và bật trạng thái cảnh báo hiện tại. Điều này đặc biệt hữu ích khi viết tệp tiêu đề sẽ được người khác biên soạn, vì bạn không biết họ xây dựng cờ cảnh báo nào.


1
Các phiên bản gần đây hơn của GCC sử dụng cùng một cú pháp (tiếng kêu thay thế cho GCC).
Niclas

3
Tôi luôn bối rối về LLVM, GCC và Clang là gì. Vì vậy, tôi muốn bỏ một ghi chú để tiết kiệm thời gian. Bộ sưu tập GNU Comp trước (GCC) đã được sử dụng với Xcode 3, sau đó Apple phát hành Xcode 4 với LLVM-GCC lai. Sau đó, trình biên dịch Máy ảo cấp thấp (LLVM) đã tiếp quản, xem thêm thông tin tại llvm.org . Kể từ Xcode 7.2.1, trình biên dịch mặc định là Apple LLVM 7.0. Trình biên dịch LLVM là một thư viện gồm các "dự án", trình gỡ lỗi và các công cụ khác, bao gồm trình biên dịch gốc Clang. Clang là trình biên dịch C / C ++ / Objective-C "LLVM".
serge-k

42

Vì chúng tôi có xu hướng cần hỗ trợ các hệ điều hành cũ hơn, nhưng chú ý đến các cảnh báo của chúng tôi, tôi muốn có một cách gọn gàng hơn để làm điều này. Tôi kết hợp nó lại với nhau, lấy cảm hứng từ một số mã Mozilla:

#define SILENCE_DEPRECATION(expr)                                   \
do {                                                                \
_Pragma("clang diagnostic push")                                    \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")   \
expr;                                                               \
_Pragma("clang diagnostic pop")                                     \
} while(0)

#define SILENCE_IOS7_DEPRECATION(expr) SILENCE_DEPRECATION(expr)
#define SILENCE_IOS8_DEPRECATION(expr) SILENCE_DEPRECATION(expr)

Điều này cho phép bạn làm như sau:

SILENCE_IOS7_DEPRECATION(return [self sizeWithFont:font constrainedToSize:size]);

Nó cũng hoạt động với các khối mã:

SILENCE_IOS7_DEPRECATION(
    view = [[MKPolylineView alloc] initWithPolyline:self];
    view.lineWidth = self.lineWidth;
    view.strokeColor = self.color;
);

Ngoài ra, khi bạn bỏ hỗ trợ cho các thiết bị trước iOS 7, bạn có thể dễ dàng tìm kiếm thông qua mã để tìm các cách sử dụng không dùng nữa để khắc phục.


đây là một giải pháp dài hạn tốt hơn nhiều cho hầu hết các mã so với việc giảm bớt các cảnh báo về sự phản đối (hoặc bất kỳ thứ gì khác) ở cấp độ toàn cầu / dự án. câu trả lời tuyệt vời.
natbro

1
Tại sao là do { ... } while(0);bắt buộc?
Ben Leggiero 15/03/2016

1
@ BenC.R.Leggiero vì bạn không vượt qua một khối mà là một vài câu giữa các dấu ngoặc đơn đó. Về cơ bản, bạn đang ngăn chặn các cảnh báo cho mỗi dòng.
Alejandro Iván

1
@ AlejandroIván Tôi biết lời giải thích của bạn có ý nghĩa với bạn ... nhưng với tôi, có vẻ như bạn đang diễn đạt lại câu hỏi. Bạn có thể giải thích tại sao do{...}while(0);đặc biệt được yêu cầu ở đây? Tại sao không chỉ{...} ? Tại sao không if(true){...}? v.v.
Ben Leggiero

2
@ BenC.R.Leggiero bạn nói đúng. Vì một số lý do tôi đọc sai câu hỏi của bạn. Kiểm tra câu trả lời được chấp nhận ở đây: stackoverflow.com/questions/154136/ từ
Alejandro Iván

29

Bạn cũng có thể chặn cảnh báo cho mỗi tệp bằng cách sử dụng

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

điều này làm cho nó thực hành tốt hơn một chút so với việc loại bỏ tất cả cảnh báo một lần và cùng nhau ... sau tất cả, bạn đã biết bạn đang làm điều đó để làm gì.


20

Nếu bạn muốn im lặng cảnh báo Thực hiện phương thức không dùng nữa hoặc Triển khai lớp không dùng nữa , hãy sử dụng:

    #pragma clang chẩn đoán đẩy
    #pragma clang chẩn đoán bị bỏ qua "-Wdeprecated-hiện thực"
    // mã
    #pragma clang chẩn đoán pop


Khi tôi thấy "-Wdeprecated-khai báo", tôi đoán phải có "-deprecated-thi hành". Và nó thực sự hoạt động. Cảm ơn bạn.
DawnSong

8

Trong cài đặt xây dựng của bạn, tìm Deprecated Functions.

nhập mô tả hình ảnh ở đây


Nó sẽ đóng tất cả các cảnh báo "không dùng nữa", tuy nhiên, chỉ một số cảnh báo cần phải được loại bỏ.
DawnSong

2

Nếu bạn muốn kiểm tra chăn cho tất cả các loại khấu hao trong một đoạn mã. Vui lòng sử dụng cờ -Wdrecated như dưới đây:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop

-3

Để tắt cảnh báo khỏi tệp tiêu đề của bên thứ ba, hãy thêm dòng sau vào đầu tệp

#pragma clang system_header
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.