@class เทียบกับ #import


709

ฉันเข้าใจว่าควรใช้การประกาศไปข้างหน้าในเหตุการณ์ ClassA ต้องรวมส่วนหัว ClassB และ ClassB ต้องรวมส่วนหัว ClassA เพื่อหลีกเลี่ยงการรวมแบบวน ฉันยังเข้าใจด้วยว่า#importa เป็นวิธีที่ง่ายifndefเพื่อให้การรวมเกิดขึ้นเพียงครั้งเดียว

คำถามของฉันคือ: เมื่อไหร่จะใช้#importและเมื่อไหร่จะใช้@class? บางครั้งถ้าฉันใช้การ@classประกาศฉันเห็นคำเตือนคอมไพเลอร์ทั่วไปเช่นต่อไปนี้:

warning: receiver 'FooController' is a forward class and corresponding @interface may not exist.

ชอบที่จะเข้าใจสิ่งนี้จริง ๆ เพียงแค่ลบการ@classประกาศไปข้างหน้าและทิ้ง#importคำเตือนที่คอมไพเลอร์ให้ฉัน


10
การประกาศล่วงหน้าเป็นการบอกคอมไพเลอร์ว่า "เฮ้ฉันรู้ว่าฉันประกาศสิ่งที่คุณไม่รู้จัก แต่เมื่อฉันพูด @MyClass ฉันสัญญาว่าฉันจะ # นำเข้าในการนำไปใช้"
JoeCortopassi

คำตอบ:


754

หากคุณเห็นคำเตือนนี้:

คำเตือน: ตัวรับ 'MyCoolClass' เป็นคลาสไปข้างหน้าและ @interface ที่เกี่ยวข้องอาจไม่มีอยู่

คุณต้องการ#importไฟล์ แต่คุณสามารถทำได้ในไฟล์การนำไปใช้ (.m) และใช้การ@classประกาศในไฟล์ส่วนหัวของคุณ

@classไม่ได้ (โดยปกติ) ลบความต้องการไปยัง#importไฟล์มันเพียงแค่ย้ายความต้องการลงไปใกล้กับที่เป็นประโยชน์ของข้อมูล

ตัวอย่างเช่น

ถ้าคุณพูด@class MyCoolClassคอมไพเลอร์รู้ว่ามันอาจเห็นสิ่งที่ชอบ:

MyCoolClass *myObject;

ไม่ต้องกังวลเกี่ยวกับสิ่งอื่นนอกจากMyCoolClassคลาสที่ถูกต้องและควรจองห้องพักสำหรับตัวชี้ (จริงๆแค่ตัวชี้) ดังนั้นในส่วนหัวของคุณ@classพอเพียง 90% ของเวลา

อย่างไรก็ตามหากคุณต้องการสร้างหรือเข้าถึงmyObjectสมาชิกคุณจะต้องแจ้งให้คอมไพเลอร์ทราบว่าวิธีการเหล่านั้นคืออะไร ณ จุดนี้ (สมมุติในไฟล์การนำไปใช้ของคุณ) คุณจะต้อง#import "MyCoolClass.h"บอกคอมไพเลอร์ข้อมูลเพิ่มเติมนอกเหนือจาก "นี่คือคลาส"


5
คำตอบที่ดีขอบคุณ สำหรับการอ้างอิงในอนาคตนี้ยังเกี่ยวข้องกับสถานการณ์ที่คุณ@classบางสิ่งบางอย่างของคุณใน.hไฟล์ แต่ลืม#importไว้ใน .m พยายามที่จะเข้าถึงวิธีการเกี่ยวกับวัตถุเอ็ดและได้รับการเตือนเช่น:@class warning: no -X method found
ทิม

24
กรณีที่คุณต้อง #import แทน @class คือถ้าไฟล์. h มีชนิดข้อมูลหรือข้อกำหนดอื่น ๆ ที่จำเป็นสำหรับอินเทอร์เฟซของคลาส
Ken Aspeslagh

2
ข้อดีอีกอย่างที่ไม่ได้กล่าวถึงในที่นี้คือการรวบรวมอย่างรวดเร็ว โปรดอ้างอิงคำตอบของ Venkateshwar
MartinMoizard

@BenGottlieb ไม่ควรที่ 'm' ใน "myCoolClass" เป็นตัวพิมพ์ใหญ่ใช่ไหม เช่นเดียวกับ "MyCoolClass"
Basil Bourque

182

กฎง่าย ๆ สามข้อ:

  • เฉพาะ#importคลาสสุดและโปรโตคอลที่นำมาใช้ในไฟล์ส่วนหัว ( .hไฟล์)
  • #importคลาสทั้งหมดและโปรโตคอลคุณส่งข้อความไปยังในการนำไปใช้ ( .mไฟล์)
  • ส่งต่อการประกาศสำหรับทุกสิ่งอื่น

หากคุณทำการส่งต่อการประกาศในไฟล์การนำไปใช้คุณอาจทำสิ่งผิดปกติ


22
ในไฟล์ส่วนหัวคุณอาจต้อง #import สิ่งใดก็ตามที่กำหนดโปรโตคอลที่คลาสของคุณใช้
ไทเลอร์

มีความแตกต่างในการประกาศ #import ในไฟล์อินเตอร์เฟส h หรือไฟล์การนำ m หรือไม่
ซามูเอลจี

และ #import ถ้าคุณใช้ตัวแปรอินสแตนซ์จากคลาส
user151019

1
@ Mark - ครอบคลุมโดยกฎ # 1 เข้าถึงได้เฉพาะ ivars จาก superclass ของคุณหากถึงตอนนั้น
PeyloW

@ ไทเลอร์ทำไมไม่ส่งต่อการประกาศของโปรโตคอล?
JoeCortopassi

110

ดูเอกสารภาษาการเขียนโปรแกรม Objective-C บนADC

ภายใต้หัวข้อการกำหนดคลาส | อินเทอร์เฟซสำหรับคลาสอธิบายถึงสาเหตุของสิ่งนี้

@class directive ลดจำนวนโค้ดที่เห็นโดยคอมไพเลอร์และลิงเกอร์ดังนั้นจึงเป็นวิธีที่ง่ายที่สุดในการประกาศล่วงหน้าของชื่อคลาส การหลีกเลี่ยงปัญหาที่อาจเกิดขึ้นจากการนำเข้าไฟล์ที่นำเข้ายังไฟล์อื่นนั้นทำได้ง่าย ตัวอย่างเช่นถ้าคลาสหนึ่งประกาศตัวแปรอินสแตนซ์ที่พิมพ์แบบสแตติกของคลาสอื่นและไฟล์อินเตอร์เฟสสองไฟล์ที่อิมพอร์ตซึ่งกันและกันคลาสใดไม่สามารถคอมไพล์ได้อย่างถูกต้อง

ฉันหวังว่านี่จะช่วยได้.


48

ใช้การประกาศไปข้างหน้าในไฟล์ส่วนหัวหากจำเป็นและ#importไฟล์ส่วนหัวสำหรับชั้นเรียนใด ๆ ที่คุณใช้ในการนำไปใช้ กล่าวอีกนัยหนึ่งก็#importคือไฟล์ที่คุณใช้ในการนำไปใช้และถ้าคุณต้องการอ้างอิงคลาสในไฟล์ส่วนหัวของคุณให้ใช้การประกาศไปข้างหน้าเช่นกัน

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


24

วิธีปฏิบัติทั่วไปคือการใช้ @class ในไฟล์ส่วนหัว (แต่คุณยังต้อง #import the superclass) และ #import ในไฟล์การใช้งาน สิ่งนี้จะหลีกเลี่ยงการรวมแบบวงกลมและใช้งานได้


2
ฉันคิดว่า #import ดีกว่า #Include ซึ่งเป็นการนำเข้าอินสแตนซ์เดียวเท่านั้นหรือ
Matthew Schinckel

2
จริง ไม่ทราบว่าเป็นเรื่องเกี่ยวกับการรวมแบบวงกลมหรือการสั่งซื้อที่ไม่ถูกต้อง แต่ฉันออกห่างจากกฎนั้น (ด้วยการนำเข้าหนึ่งรายการในส่วนหัวการนำเข้าไม่จำเป็นอีกต่อไปในการใช้งานของคลาสย่อย) และเร็ว ๆ นี้ บรรทัดล่างทำตามกฎนั้นและคอมไพเลอร์จะมีความสุข
Steph Thirion

1
เอกสารปัจจุบันบอกว่า#import"เป็นเหมือนคำสั่ง #include ของ C, ยกเว้นว่าจะทำให้แน่ใจว่าไฟล์เดียวกันจะไม่รวมอยู่มากกว่าหนึ่งครั้ง." ดังนั้นสิ่งนี้#importจึงรวมการวนเป็นวงกลม@classคำสั่งไม่ได้ช่วยอะไรเป็นพิเศษ
Eric

24

ข้อได้เปรียบอีกประการหนึ่ง: การรวบรวมอย่างรวดเร็ว

หากคุณรวมไฟล์ส่วนหัวการเปลี่ยนแปลงใด ๆ ในนั้นจะทำให้ไฟล์ปัจจุบันนั้นคอมไพล์ด้วย แต่นี่ไม่ใช่กรณีหากชื่อคลาสรวมอยู่@class nameด้วย แน่นอนคุณจะต้องรวมส่วนหัวในไฟล์ต้นฉบับ


18

คำถามของฉันคือสิ่งนี้ เมื่อใดจึงใช้ #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>) สิ่งนี้สามารถแนะนำการพึ่งพาได้ แต่ผู้ดูแลห้องสมุดสามารถจัดการการพึ่งพาทางกายภาพสำหรับคุณได้ตามต้องการ - หากพวกเขาแนะนำคุณลักษณะพวกเขาสามารถลดผลกระทบที่มีต่องานสร้างของคุณได้


BTW พยายามอย่างยิ่งที่จะอธิบายสิ่งต่าง ๆ แต่ดูเหมือนพวกเขาจะค่อนข้างซับซ้อน
Ajay Sharma

NSObject types are never values -- NSObject types are always reference counted pointers.ไม่จริงทั้งหมด บล็อกโยนช่องโหว่ในคำตอบของคุณเพียงแค่พูด
Richard J. Ross III

@ RichardJ.RossIII …และ GCC อนุญาตให้หนึ่งประกาศและใช้ค่าในขณะที่เสียงดังกราวห้ามมัน และแน่นอนว่าต้องมีค่าอยู่หลังตัวชี้
justin

11

ฉันเห็นจำนวนมากของ "ทำแบบนี้" แต่ฉันไม่เห็นคำตอบของ "ทำไม"

ดังนั้น: ทำไมคุณถึง @ class ในส่วนหัวของคุณและ #import ในการติดตั้งของคุณเท่านั้น คุณเพิ่มงานของคุณเป็นสองเท่าโดยใช้ @class และ #import ตลอดเวลา เว้นแต่ว่าคุณจะใช้ประโยชน์จากมรดก ในกรณีนี้คุณจะ #importing @class เดียวหลายครั้ง จากนั้นคุณต้องอย่าลืมลบไฟล์ต่าง ๆ หลายไฟล์หากคุณตัดสินใจโดยทันทีว่าคุณไม่ต้องการใช้การประกาศอีกต่อไป

การนำเข้าไฟล์เดียวกันหลายครั้งไม่ใช่ปัญหาเนื่องจากลักษณะของ #import ประสิทธิภาพการรวบรวมไม่ได้เป็นปัญหาเช่นกัน หากเป็นเช่นนั้นเราจะไม่ #importing Cocoa / Cocoa.h หรือเหมือนในไฟล์ส่วนหัวทุกไฟล์ที่เรามี


1
ดูคำตอบของ Abizem ด้านบนเพื่อดูตัวอย่างจากเอกสารอธิบายสาเหตุที่คุณควรทำ มันเป็นโปรแกรมป้องกันเมื่อคุณมีสองส่วนหัวคลาสที่นำเข้าซึ่งกันและกันด้วยตัวแปรอินสแตนซ์ของคลาสอื่น ๆ
jackslash

7

ถ้าเราทำสิ่งนี้

@interface Class_B : Class_A

หมายความว่าเรากำลังสืบทอด Class_A ไปสู่ ​​Class_B ใน Class_B เราสามารถเข้าถึงตัวแปรทั้งหมดของ class_A

ถ้าเราทำเช่นนี้

#import ....
@class Class_A
@interface Class_B

ที่นี่เราบอกว่าเรากำลังใช้ Class_A ในโปรแกรมของเรา แต่ถ้าเราต้องการใช้ตัวแปร Class_A ใน Class_B เราต้อง #import Class_A ในไฟล์. m (ทำให้วัตถุและใช้เป็นฟังก์ชันและตัวแปร)


5

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการอ้างอิงไฟล์ & #import & @class ลองดู:

http://qualitycoding.org/file-dependencies/ มัน เป็นบทความที่ดี

บทสรุปของบทความ

นำเข้าในไฟล์ส่วนหัว:

  • #import superclass ที่คุณกำลังสืบทอดและโปรโตคอลที่คุณใช้งานอยู่
  • ส่งต่อ - ประกาศทุกอย่างอื่น (เว้นแต่ว่ามาจากกรอบงานที่มีส่วนหัวหลัก)
  • พยายามกำจัด #imports อื่น ๆ ทั้งหมด
  • ประกาศโปรโตคอลในส่วนหัวของตนเองเพื่อลดการพึ่งพา
  • มีการประกาศไปข้างหน้ามากเกินไป? คุณมีชั้นเรียนขนาดใหญ่

นำเข้าในไฟล์การนำไปใช้งาน:

  • กำจัด cruft #imports ที่ไม่ได้ใช้
  • หากวิธีการมอบหมายให้วัตถุอื่นและส่งคืนสิ่งที่ได้รับกลับมาลองส่งต่อประกาศวัตถุนั้นแทน #importing
  • หากการรวมโมดูลบังคับให้คุณรวมระดับหลังจากระดับการพึ่งพาต่อเนื่องคุณอาจมีชุดของคลาสที่ต้องการเป็นห้องสมุด สร้างเป็นห้องสมุดแยกต่างหากพร้อมด้วยส่วนหัวหลักเพื่อให้ทุกอย่างสามารถนำมาเป็นชิ้นย่อยที่สร้างไว้ล่วงหน้าเดียว
  • มี #imports มากเกินไปหรือไม่ คุณมีชั้นเรียนขนาดใหญ่

3

เมื่อฉันพัฒนาฉันมีสามสิ่งในใจที่ไม่เคยทำให้ฉันมีปัญหาใด ๆ

  1. นำเข้าซุปเปอร์คลาส
  2. นำเข้าชั้นผู้ปกครอง (เมื่อคุณมีลูกและผู้ปกครอง)
  3. นำเข้าคลาสนอกโครงการของคุณ (เช่นในกรอบงานและไลบรารี)

สำหรับคลาสอื่นทั้งหมด (คลาสย่อยและคลาสย่อยในโปรเจ็กต์ของฉันเอง) ฉันประกาศคลาสเหล่านี้ผ่านคลาสไปข้างหน้า


3

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

ความคิดแรกของคุณน่าจะ#importเป็น
นี่อาจทำให้เกิดปัญหาในบางกรณี

ตัวอย่างเช่นถ้าคุณใช้วิธีการ C จำนวนมากในไฟล์ส่วนหัวหรือ structs หรือสิ่งที่คล้ายกันเพราะพวกเขาไม่ควรนำเข้าหลายครั้ง

ดังนั้นคุณสามารถบอกคอมไพเลอร์ด้วย@class:

ฉันรู้ว่าคุณไม่ทราบชั้นเรียนนั้น แต่มันมีอยู่ มันจะถูกนำเข้าหรือนำไปใช้ที่อื่น

มันบอกคอมไพเลอร์ว่าให้ปิดและเรียบเรียงแม้ว่ามันจะไม่แน่ใจว่าคลาสนี้จะถูกนำไปใช้หรือไม่

โดยปกติคุณจะใช้#importในไฟล์. mและ@classในไฟล์. h


0

ส่งต่อการประกาศเพียงเพื่อป้องกันคอมไพเลอร์จากการแสดงข้อผิดพลาด

คอมไพเลอร์จะรู้ว่ามีคลาสที่มีชื่อที่คุณใช้ในไฟล์ส่วนหัวของคุณเพื่อประกาศ


คุณจะเจาะจงมากกว่านี้หน่อยได้ไหม?
Sam Spencer

0

คอมไพเลอร์จะบ่นก็ต่อเมื่อคุณจะใช้คลาสนั้นในลักษณะที่คอมไพเลอร์จำเป็นต้องรู้ถึงการนำไปใช้

Ex:

  1. อาจเป็นเช่นนี้หากคุณจะได้รับคลาสของคุณจากมันหรือ
  2. หากคุณจะมีวัตถุของคลาสนั้นเป็นตัวแปรสมาชิก (แม้ว่าจะหายาก)

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

หมายเหตุ: #import ไม่เหมือนกับ #include ซึ่งหมายความว่าไม่มีสิ่งใดที่เรียกว่าการนำเข้าแบบวงกลม import เป็นชนิดของการร้องขอให้คอมไพเลอร์มองเข้าไปในไฟล์เฉพาะสำหรับข้อมูลบางอย่าง หากข้อมูลนั้นมีอยู่แล้วคอมไพเลอร์จะข้ามข้อมูลนั้นไป

ลองใช้วิธีนี้นำเข้า Ah ใน Bh และ Bh ใน Ah จะไม่มีปัญหาหรือข้อร้องเรียนและจะทำงานได้ดีเช่นกัน

เมื่อใดที่จะใช้ @class

คุณใช้ @class เฉพาะในกรณีที่คุณไม่ต้องการนำเข้าส่วนหัวในส่วนหัวของคุณ นี่อาจเป็นกรณีที่คุณไม่สนใจแม้แต่จะรู้ว่าคลาสนั้นจะเป็นเช่นไร กรณีที่คุณอาจไม่มีส่วนหัวสำหรับคลาสนั้น

ตัวอย่างนี้อาจเป็นได้ว่าคุณกำลังเขียนห้องสมุดสองแห่ง มีหนึ่งคลาสให้เรียกมันว่า A มีอยู่ในห้องสมุดเดียว ห้องสมุดนี้มีส่วนหัวจากห้องสมุดที่สอง ส่วนหัวนั้นอาจมีตัวชี้ A แต่อีกครั้งอาจไม่จำเป็นต้องใช้ หากยังไม่มีไลบรารี่ 1 ไลบรารี B จะไม่ถูกบล็อกหากคุณใช้ @class แต่ถ้าคุณต้องการนำเข้า Ah ความคืบหน้าของไลบรารี 2 จะถูกบล็อก


0

คิดว่า @class เป็นการบอกคอมไพเลอร์ "เชื่อฉันสิมันมีอยู่"

คิดว่า #import เป็น copy-paste

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

โปรดสังเกตว่าเมื่อคุณสืบทอดจากคลาสคุณไม่สามารถใช้การประกาศไปข้างหน้าได้ คุณต้องนำเข้าไฟล์เพื่อให้คลาสที่คุณประกาศรู้ว่ามันถูกกำหนดไว้อย่างไร


0

นี่คือสถานการณ์ตัวอย่างที่เราต้องการ @class

พิจารณาว่าคุณต้องการสร้างโปรโตคอลภายในไฟล์ส่วนหัวซึ่งมีพารามิเตอร์ที่มีชนิดข้อมูลของคลาสเดียวกันหรือไม่คุณสามารถใช้ @class โปรดจำไว้ว่าคุณยังสามารถประกาศโปรโตคอลแยกต่างหากนี่เป็นเพียงตัวอย่าง

// DroneSearchField.h

#import <UIKit/UIKit.h>
@class DroneSearchField;
@protocol DroneSearchFieldDelegate<UITextFieldDelegate>
@optional
- (void)DroneTextFieldButtonClicked:(DroneSearchField *)textField;
@end
@interface DroneSearchField : UITextField
@end
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.