วิธีตรวจหาวิธีที่ไม่ได้ใช้และ #import ใน Objective-C


100

หลังจากทำงานกับแอพ iPhone เป็นเวลานานฉันตระหนักว่ารหัสของฉันค่อนข้างสกปรกมี #import และวิธีการหลายอย่างที่ไม่ได้เรียกหรือมีประโยชน์เลย

ฉันต้องการทราบว่ามีคำสั่งคอมไพเลอร์หรือวิธีตรวจจับบรรทัดโค้ดที่ไร้ประโยชน์เหล่านั้นหรือไม่ Xcode มีเครื่องมือตรวจจับสิ่งนี้หรือไม่?

คำตอบ:


66

Xcode ช่วยให้คุณ (ยกเลิก) ตรวจสอบการตั้งค่าสำหรับคำเตือนของคอมไพเลอร์เฉพาะที่สามารถเตือนคุณเกี่ยวกับรหัสที่ไม่ได้ใช้บางประเภท (เลือกโปรเจ็กต์ในรายการต้นทางและไฟล์> รับข้อมูลจากนั้นเลือกแท็บสร้าง) นี่คือบางส่วน (ซึ่งแสดงสำหรับ Clang และ GCC 4.2 สำหรับฉัน) ซึ่งอาจเป็นที่สนใจ:

  • ฟังก์ชั่นที่ไม่ได้ใช้
  • พารามิเตอร์ที่ไม่ได้ใช้
  • ค่าที่ไม่ได้ใช้

ฉันไม่เห็นตัวเลือกใด ๆ ในการตรวจจับการนำเข้าที่ไม่ได้ใช้ แต่มันค่อนข้างง่ายกว่าเล็กน้อย - วิธีการที่ใช้เทคโนโลยีขั้นต่ำเพียงแค่แสดงความคิดเห็นในคำสั่งนำเข้าจนกว่าคุณจะได้รับข้อผิดพลาด / คำเตือนในการคอมไพล์

เมธอด Objective-C ที่ไม่ได้ใช้นั้นตรวจจับได้ยากกว่าฟังก์ชัน C ที่ไม่ได้ใช้มากเนื่องจากข้อความจะถูกส่งแบบไดนามิก คำเตือนหรือข้อผิดพลาดสามารถบอกคุณได้ว่าคุณอาจมีปัญหา แต่การขาดอย่างใดอย่างหนึ่งไม่ได้รับประกันว่าคุณจะไม่มีข้อผิดพลาดรันไทม์


แก้ไข:อีกวิธีหนึ่งที่ดีในการตรวจหาวิธีที่ไม่ได้ใช้ (อาจ) คือการตรวจสอบความครอบคลุมของรหัสจากการดำเนินการจริง โดยปกติจะทำควบคู่ไปกับการทดสอบหน่วยอัตโนมัติ แต่ไม่จำเป็นต้องทำ

บล็อกโพสต์นี้เป็นการแนะนำที่ดีเกี่ยวกับการทดสอบหน่วยและการครอบคลุมโค้ดโดยใช้ Xcode ส่วนบนgcov(ซึ่งใช้งานได้กับโค้ดที่สร้างโดย GCC เท่านั้น) อธิบายถึงวิธีรับ Xcode เพื่อสร้างโค้ดที่เป็นเครื่องมือซึ่งสามารถบันทึกความถี่ในการเรียกใช้งาน หากคุณใช้เครื่องมือสร้างแอปของคุณเพื่อหมุนในเครื่องจำลองจากนั้นเรียกใช้ gcov บนแอปคุณจะเห็นว่าโค้ดใดถูกเรียกใช้โดยใช้เครื่องมือเช่นCoverStory (GUI ที่ค่อนข้างง่าย) หรือlcov(สคริปต์ Perl เพื่อสร้างรายงาน HTML) .

ฉันใช้gcovและlcovสำหรับCHDataStructures.frameworkและสร้างรายงานความครอบคลุมโดยอัตโนมัติหลังจากการคอมมิต SVN แต่ละครั้ง โปรดจำไว้อีกครั้งว่าไม่ฉลาดที่จะถือว่าการดำเนินการครอบคลุมเป็นตัวชี้วัดที่ชัดเจนว่ารหัสใด "ตาย" แต่ก็สามารถช่วยระบุวิธีการที่คุณสามารถตรวจสอบเพิ่มเติมได้

สุดท้ายนี้เนื่องจากคุณกำลังพยายามลบรหัสที่ตายแล้วฉันคิดว่าคุณจะพบว่าคำถาม SO นี้น่าสนใจเช่นกัน:


4
ฉันไม่แน่ใจว่าประเด็นของคุณคืออะไร ... ตัววิเคราะห์แบบคงที่อาจพบปัญหามากมาย แต่ถ้าคุณส่งข้อความไปยังตัวแปรที่พิมพ์เป็นidหรือสร้างตัวเลือกเพื่อเรียกใช้ขณะรันไทม์ตัววิเคราะห์แบบคงไม่สามารถรับประกันได้ รหัสนั้นไม่ได้ถูกใช้อย่างแท้จริง หากรหัสที่ยังต้องการถูกลบออกนั่นคือจุดที่คุณจะได้รับข้อผิดพลาดรันไทม์ ฉันพลาดอะไรไปรึเปล่า?
Quinn Taylor

1
นอกจากนี้ตัวเลือกที่สร้างขึ้นตามสตริงในรันไทม์นั้นค่อนข้างธรรมดา
dreamlax

1
แน่นอนว่ามีหลายกรณีที่โค้ดไดนามิกของคุณอาจแสดงผลได้ดีขึ้นโดยการแคสต์ประเภทที่รุนแรงกว่า (เช่นส่งคืนค่าบางอย่างแทน id) การพิมพ์รันไทม์เป็นจุดแข็งของการเขียนโปรแกรม Cocoa / Objective-C แต่บางครั้งการบำรุงรักษาและความสามารถในการอ่านจะได้รับการตอบสนองที่ดีขึ้นโดยการคิดถึงการพิมพ์ที่ชัดเจน
alesplin

3
โอ้ฉันเห็นด้วยแน่นอน หลักการทั่วไปของฉันคือการพิมพ์แบบคงที่ (เช่นเดียวกับที่ฉันทำใน Java) เว้นแต่ฉันต้องการการพิมพ์แบบไดนามิกซึ่งหาได้ยาก แต่เกิดขึ้นในบางโอกาส อย่างไรก็ตามการเชื่อมต่อกับคลาส Cocoa (ตัวอย่างเช่นการระบุผู้ร่วมประชุม) อาจส่งผลให้เกิดพลวัตและเส้นทางการดำเนินการที่ยากต่อการติดตาม Heck โปรแกรมใด ๆ ที่มี run loop และหลายเธรดอาจไม่สำคัญ ...
Quinn Taylor

40

Appcodeมีคุณสมบัติการตรวจสอบโค้ดซึ่งจะค้นหาการนำเข้าและโค้ดที่ไม่ได้ใช้


18
ดังนั้นคุณหมายความว่าเราควรติดตั้ง Appcode สำหรับคุณสมบัตินี้หรือไม่?
mayqiyue

ถ้ามันมีประโยชน์กับคุณใช่!
rmp251


5

ฉันเพิ่งเขียนสคริปต์เพื่อค้นหาสิ่งที่ไม่ได้ใช้ (หรือซ้ำกัน) #import : https://gist.github.com/Orangenhain/7691314

สคริปต์ใช้ไฟล์ ObjC .m และเริ่มแสดงความคิดเห็นในแต่ละ#importบรรทัดตามลำดับและดูว่าโปรเจ็กต์ยังคอมไพล์อยู่หรือไม่ คุณจะต้องเปลี่ยน BUILD_DIR & BUILD_CMD

หากคุณใช้findคำสั่งเพื่อให้สคริปต์ทำงานบนไฟล์หลายไฟล์ตรวจสอบให้แน่ใจว่าได้ใช้ BUILD_CMD ที่จริงใช้ไฟล์เหล่านั้น (หรือคุณจะเห็นไฟล์ที่มีคำสั่งการนำเข้าที่ไม่ได้ใช้จำนวนมาก)

ฉันเขียนสิ่งนี้โดยไม่รู้ว่า AppCode มีคุณสมบัติที่คล้ายกัน แต่เมื่อฉันทดสอบ AppCode มันไม่ละเอียดเท่าสคริปต์นี้ (แต่เร็วกว่า [สำหรับทั้งโครงการ])


มันทำงานสำหรับรายการที่ซ้ำกันเท่านั้นการนำเข้าที่ไม่ได้ใช้จะไม่ถูกลบออก
Rahul

4

ดังที่คุณpaddydubกล่าวไว้ว่าAppCodeทำได้ดีมาก ฉันลองแล้วและใช้เวลาแค่ 10 นาที:

ไปที่Code > Optimize Imports...หรือ^ + ⌥ + O

นี่คือวิดีโอที่อธิบายวิธีการดำเนินการ: การตรวจหาการนำเข้าที่ไม่ได้ใช้และวิธีการใน AppCode


2

คุณสามารถใช้ Xcode Analyzer เพื่อค้นหาสิ่งนั้นและปัญหาอื่น ๆ

http://help.apple.com/xcode/mac/8.0/#/devb7babe820

นอกจากนี้คุณสามารถไปที่โครงการและกำหนดเป้าหมายบิลด์และเพิ่มการตั้งค่าคำเตือนการเปลี่ยนแปลงภายใต้การตั้งค่าบิลด์ ดูคู่มือนี้:

http://oleb.net/blog/2013/04/compiler-warnings-for-objective-c-developers/


1

เมื่อเร็ว ๆ นี้ฉันเปลี่ยนโครงการขนาดใหญ่จากคาร์บอนเป็นโกโก้ ในตอนท้ายของสิ่งนี้มีไฟล์ที่ไม่มีใครใช้งานอีกต่อไป ฉันเขียนสคริปต์เพื่อค้นหาพวกเขาที่ทำสิ่งนี้เป็นหลัก:

ตรวจสอบให้แน่ใจว่าแหล่งที่มาทั้งหมดถูกตรวจสอบในการโค่นล้ม (เช่นสะอาด) ตรวจสอบให้แน่ใจว่ากำลังสร้างโดยไม่มีข้อผิดพลาด (เช่น xcodebuild ส่งคืนสถานะ 0) จากนั้นสำหรับไฟล์ต้นฉบับแต่ละไฟล์ในไดเร็กทอรีว่าง (เช่นลบเนื้อหาตัดความยาว) ซอร์สและไฟล์ส่วนหัวลองสร้างหากล้มเหลวให้เปลี่ยนกลับไฟล์มิฉะนั้นปล่อยให้ว่างเปล่า

หลังจากรันสิ่งนี้ให้เปลี่ยนกลับแล้วลบไฟล์ที่ว่างเปล่าทั้งหมดคอมไพล์แล้วลบ #imports ที่ผิดพลาดทั้งหมด

ฉันควรเพิ่มคุณต้องหลีกเลี่ยงไฟล์ที่อ้างอิงจากไฟล์. xib หรือ. sdef และอาจมีกรณีการเชื่อมโยงแบบไดนามิกอื่น ๆ แต่ก็ยังสามารถให้โอกาสที่ดีแก่คุณเกี่ยวกับสิ่งที่สามารถลบได้

สามารถใช้เทคนิคเดียวกันนี้เพื่อดูว่า #import ใดที่สามารถลบออกได้ - แทนที่จะตัดทอนไฟล์ให้ลบ #import แต่ละไฟล์ออกจากกันและดูว่าบิลด์ล้มเหลวหรือไม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.