คำถามของฉันคือสิ่งนี้ เมื่อใดจึงใช้ #import และเมื่อใดที่ใช้ @class
คำตอบง่ายๆ: คุณ#import
หรือ#include
เมื่อมีการพึ่งพาทางกายภาพ มิฉะนั้นคุณจะใช้การประกาศไปข้างหน้า ( @class MONClass
, struct MONStruct
, @protocol MONProtocol
)
นี่คือตัวอย่างทั่วไปของการพึ่งพาทางกายภาพ:
- ค่า C หรือ C ++ ใด ๆ (ตัวชี้หรือการอ้างอิงไม่ใช่การอ้างอิงทางกายภาพ) หากคุณมีความ
CGPoint
เป็น Ivar CGPoint
หรือทรัพย์สินคอมไพเลอร์จะต้องเห็นประกาศของ
- ซูเปอร์คลาสของคุณ
- วิธีที่คุณใช้
บางครั้งถ้าฉันใช้การประกาศ @class ฉันเห็นคำเตือนคอมไพเลอร์ทั่วไปเช่นต่อไปนี้: "warning: receiver 'FooController' เป็นคลาสไปข้างหน้าและ @interface ที่เกี่ยวข้องอาจไม่มีอยู่"
คอมไพเลอร์นั้นอ่อนโยนจริงๆในเรื่องนี้ มันจะวางคำใบ้ (เช่นที่ด้านบน) แต่คุณสามารถทิ้งสแต็คของคุณได้อย่างง่ายดายหากคุณไม่สนใจและไม่#import
เหมาะสม แม้ว่ามันควรจะ (IMO) คอมไพเลอร์ไม่บังคับใช้ ใน ARC คอมไพเลอร์เข้มงวดมากขึ้นเนื่องจากรับผิดชอบการนับการอ้างอิง สิ่งที่เกิดขึ้นคือคอมไพเลอร์ตกลงบนค่าเริ่มต้นเมื่อพบวิธีที่ไม่รู้จักซึ่งคุณเรียกใช้ id
ค่าตอบแทนทุกพารามิเตอร์จะถือว่า ดังนั้นคุณควรกำจัดทุกคำเตือนจากรหัสฐานเพราะสิ่งนี้ควรพิจารณาการพึ่งพาทางกายภาพ สิ่งนี้คล้ายคลึงกับการเรียกใช้ฟังก์ชัน C ซึ่งไม่ได้ประกาศไว้ ด้วย C int
พารามิเตอร์จะถือว่าเป็น
เหตุผลที่คุณต้องการสนับสนุนการประกาศล่วงหน้าคือคุณสามารถลดเวลาสร้างของคุณตามปัจจัยต่าง ๆ ได้เนื่องจากมีการพึ่งพาน้อยที่สุด ด้วยการประกาศไปข้างหน้าคอมไพเลอร์เห็นว่ามีชื่อและสามารถแยกวิเคราะห์และรวบรวมโปรแกรมได้อย่างถูกต้องโดยไม่เห็นการประกาศคลาสหรือการอ้างอิงทั้งหมดเมื่อไม่มีการพึ่งพาทางกายภาพ งานสร้างที่สะอาดใช้เวลาน้อยลง งานสร้างที่เพิ่มขึ้นใช้เวลาน้อยลง แน่นอนว่าคุณจะต้องเสียเวลาอีกเล็กน้อยเพื่อให้แน่ใจว่าส่วนหัวทั้งหมดที่คุณต้องการจะปรากฏให้เห็นในการแปลทุกครั้ง แต่สิ่งนี้จะช่วยลดเวลาในการสร้างได้อย่างรวดเร็ว (สมมติว่าโครงการของคุณไม่เล็ก)
หากคุณใช้งาน#import
หรือ#include
แทนคุณจะทิ้งงานคอมไพเลอร์มากกว่าที่จำเป็น คุณกำลังแนะนำการพึ่งพาส่วนหัวที่ซับซ้อน คุณสามารถเปรียบสิ่งนี้กับอัลกอริทึมกำลังดุร้าย เมื่อคุณ#import
คุณกำลังลากข้อมูลที่ไม่จำเป็นจำนวนมากซึ่งต้องการหน่วยความจำจำนวนมากดิสก์ I / O และ CPU เพื่อแยกวิเคราะห์และคอมไพล์แหล่งที่มา
ObjC นั้นค่อนข้างใกล้เคียงกับอุดมคติสำหรับภาษาที่ใช้ภาษา C โดยคำนึงถึงการพึ่งพาเนื่องจากNSObject
ชนิดไม่เคยมีค่า - NSObject
ประเภทนั้นเป็นตัวชี้นับที่อ้างอิงเสมอ ดังนั้นคุณสามารถหลีกเลี่ยงการรวบรวมเวลาที่รวดเร็วอย่างไม่น่าเชื่อถ้าคุณจัดโครงสร้างการพึ่งพาโปรแกรมของคุณอย่างเหมาะสมและส่งต่อเมื่อทำได้เนื่องจากมีการพึ่งพาทางกายภาพเพียงเล็กน้อย คุณยังสามารถประกาศคุณสมบัติในส่วนขยายคลาสเพื่อลดการพึ่งพาเพิ่มเติม นั่นเป็นโบนัสใหญ่สำหรับระบบขนาดใหญ่ - คุณจะรู้ถึงความแตกต่างที่เกิดขึ้นหากคุณเคยพัฒนารหัสฐาน C ++ ขนาดใหญ่
ดังนั้นคำแนะนำของฉันคือการใช้ส่งต่อที่เป็นไปได้แล้วไปยัง#import
ที่ที่มีการพึ่งพาทางกายภาพ หากคุณเห็นคำเตือนหรือคำเตือนอื่นซึ่งหมายถึงการพึ่งพาทางกายภาพ - แก้ไขทั้งหมด การแก้ไขคือ#import
ในไฟล์การใช้งานของคุณ
ในขณะที่คุณสร้างไลบรารีคุณอาจจัดประเภทอินเทอร์เฟซบางอย่างเป็นกลุ่มซึ่งในกรณีนี้คุณจะใช้#import
ไลบรารีที่แนะนำการพึ่งพาทางกายภาพ (เช่น#import <AppKit/AppKit.h>
) สิ่งนี้สามารถแนะนำการพึ่งพาได้ แต่ผู้ดูแลห้องสมุดสามารถจัดการการพึ่งพาทางกายภาพสำหรับคุณได้ตามต้องการ - หากพวกเขาแนะนำคุณลักษณะพวกเขาสามารถลดผลกระทบที่มีต่องานสร้างของคุณได้