Cách phát hiện các phương thức không sử dụng và #import trong Objective-C


99

Sau một thời gian dài làm việc trên ứng dụng iPhone, tôi nhận ra rằng mã của mình khá bẩn, chứa một số #import và các phương thức không được gọi hoặc hữu ích chút nào.

Tôi muốn biết nếu có bất kỳ chỉ thị trình biên dịch hoặc cách nào để phát hiện những dòng mã vô dụng đó. Xcode có bất kỳ công cụ nào để phát hiện điều này không?

Câu trả lời:


66

Xcode cho phép bạn (bỏ) kiểm tra cài đặt cho các cảnh báo trình biên dịch cụ thể có thể cảnh báo bạn về một số loại mã không sử dụng. (Chọn dự án trong danh sách nguồn và Tệp> Nhận Thông tin, sau đó chọn tab Xây dựng.) Dưới đây là một số (hiển thị cho Clang và GCC 4.2 đối với tôi) có thể quan tâm:

  • Các chức năng không được sử dụng
  • Tham số không sử dụng
  • Giá trị không được sử dụng

Tôi không thấy bất kỳ tùy chọn nào để phát hiện các lần nhập chưa sử dụng, nhưng điều đó đơn giản hơn một chút - cách tiếp cận công nghệ thấp chỉ là nhận xét các câu lệnh nhập cho đến khi bạn gặp lỗi / cảnh báo biên dịch.

Các phương thức Objective-C không được sử dụng khó phát hiện hơn nhiều so với các hàm C không được sử dụng vì các thông báo được gửi động. Một cảnh báo hoặc một lỗi có thể cho bạn biết rằng bạn có một sự cố tiềm ẩn, nhưng việc thiếu một cảnh báo không đảm bảo rằng bạn sẽ không gặp phải lỗi thời gian chạy.


Chỉnh sửa: Một cách hay khác để phát hiện các phương thức không được sử dụng (có khả năng) là kiểm tra độ bao phủ của mã từ các lần thực thi thực tế. Điều này thường được thực hiện song song với kiểm thử đơn vị tự động, nhưng không nhất thiết phải như vậy.

Bài đăng trên blog này là một giới thiệu tốt về kiểm thử đơn vị và phạm vi mã bằng Xcode. Phần trên gcov(nhân tiện chỉ hoạt động với mã do GCC tạo ra) giải thích cách lấy Xcode để xây dựng mã công cụ có thể ghi lại tần suất nó đã được thực thi. Nếu bạn sử dụng một bản dựng công cụ của ứng dụng để quay trong trình mô phỏng, sau đó chạy gcov trên đó, bạn có thể xem mã nào đã được thực thi bằng cách sử dụng một công cụ như CoverStory (một GUI khá đơn giản) hoặc lcov(Perl script để tạo báo cáo HTML) .

Tôi sử dụng gcovlcovcho CHDataStructures.framework và tự động tạo báo cáo phạm vi sau mỗi cam kết SVN. Một lần nữa, hãy nhớ rằng không khôn ngoan nếu coi phạm vi bảo hiểm được thực thi như một thước đo xác định về mã nào là "chết", nhưng nó chắc chắn có thể giúp xác định các phương pháp mà bạn có thể điều tra thêm.

Cuối cùng, vì bạn đang cố gắng xóa mã chết, tôi nghĩ bạn cũng sẽ thấy câu hỏi SO này thú vị:


4
Tôi không chắc quan điểm của bạn là gì ... Trình phân tích tĩnh có thể tìm thấy nhiều vấn đề, nhưng nếu bạn gửi thông báo đến một biến được nhập là idhoặc tạo một bộ chọn để gọi trong thời gian chạy, thì trình phân tích tĩnh không thể đảm bảo rằng mã thực sự không được sử dụng. Nếu mã vẫn cần thiết bị xóa, đó là nơi bạn sẽ gặp lỗi thời gian chạy. Tui bỏ lỡ điều gì vậy?
Quinn Taylor

1
Hơn nữa, các bộ chọn được tạo dựa trên các chuỗi trong thời gian chạy là khá phổ biến.
dreamlax 22/09/09

1
Tất nhiên, có những trường hợp mã động của bạn có thể được phân phát tốt hơn bằng cách nhập kiểu mạnh hơn (nghĩa là trả về một cái gì đó thay vì một id). Nhập thời gian chạy là một điểm mạnh của lập trình Cocoa / Objective-C, nhưng đôi khi việc bảo trì và khả năng đọc sẽ được phục vụ tốt hơn bằng cách suy nghĩ nhiều hơn về cách gõ mạnh.
alesplin 22/09/09

3
Ồ, tôi chắc chắn đồng ý. Quy tắc ngón tay cái của tôi là nhập tĩnh (như tôi làm trong Java) trừ khi tôi thực sự cần nhập động, điều này hiếm khi xảy ra nhưng thỉnh thoảng xảy ra. Tuy nhiên, chỉ cần giao tiếp với các lớp Cocoa (ví dụ: chỉ định một đại biểu) có thể dẫn đến tính năng động và đường dẫn thực thi khó theo dõi. Heck, bất kỳ chương trình với một vòng lặp chạy và nhiều chủ đề có thể không tầm thường ...
Quinn Taylor

39

Appcode có tính năng kiểm tra mã để tìm các mã nhập và mã chưa sử dụng.


18
Vì vậy, ý bạn là chúng ta nên cài đặt Appcode chỉ cho tính năng này?
mayqiyue

Nếu nó hữu ích cho bạn, có!
rmp251


5

Gần đây tôi đã viết một tập lệnh để tìm các #importcâu lệnh không được sử dụng (hoặc trùng lặp) : https://gist.github.com/Orangenhain/7691314

Tập lệnh lấy một tệp ObjC .m và bắt đầu nhận xét #importlần lượt từng dòng và xem liệu dự án có còn biên dịch hay không. Bạn sẽ phải thay đổi BUILD_DIR & BUILD_CMD.

Nếu bạn đang sử dụng findlệnh để cho tập lệnh chạy trên nhiều tệp, hãy đảm bảo sử dụng BUILD_CMD thực sự sử dụng tất cả các tệp đó (hoặc bạn sẽ thấy một tệp có nhiều câu lệnh nhập không sử dụng).

Tôi đã viết cái này mà không biết AppCode có một tính năng tương tự, tuy nhiên khi tôi thử nghiệm AppCode, nó không kỹ lưỡng như tập lệnh này (nhưng nhanh hơn [cho toàn bộ dự án]).


Nó chỉ hoạt động cho các bản sao, các bản nhập không sử dụng sẽ không bị xóa.
Rahul



1

Gần đây, tôi đã thay đổi một dự án lớn từ Carbon sang Cocoa. Cuối cùng, có khá nhiều tệp mồ côi đã không còn được sử dụng. Tôi đã viết một kịch bản để tìm chúng về cơ bản đã làm điều này:

Đảm bảo rằng tất cả nguồn đã được đăng ký vào subversion (tức là sạch) Đảm bảo rằng nó hiện đang xây dựng mà không có lỗi (tức là xcodebuild trả về trạng thái 0) Sau đó, đối với mỗi tệp nguồn trong thư mục, trống (tức là xóa nội dung, cắt bớt độ dài) nguồn và tệp tiêu đề, hãy thử một bản dựng, nếu nó không thành công, hãy hoàn nguyên các tệp, nếu không, hãy để chúng trống.

Sau khi chạy, hãy hoàn nguyên và sau đó xóa tất cả các tệp đã làm trống, biên dịch và sau đó xóa tất cả các lỗi #imports.

Tôi cũng nên nói thêm, bạn cần tránh các tệp được tham chiếu từ tệp .xib hoặc .sdef và có thể có các trường hợp liên kết động khác, nhưng nó vẫn có thể cung cấp cho bạn một hướng dẫn tốt về những gì có thể bị xóa.

Kỹ thuật tương tự cũng có thể được sử dụng để xem có thể loại bỏ #import nào - thay vì cắt bớt tệp, hãy xóa lần lượt từng #import trong tệp và xem bản dựng có bị lỗi không.

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.