อะไรคือความแตกต่างระหว่างหมวดหมู่และส่วนขยายคลาส ฉันเชื่อว่าทั้งสองใช้เพื่อเพิ่มวิธีการที่กำหนดเองในคลาสที่มีอยู่ ใครบางคนสามารถให้ความสำคัญกับเรื่องนี้ได้หรือไม่? การตรวจสอบด้วยรหัสจะได้รับการชื่นชมอย่างมาก
อะไรคือความแตกต่างระหว่างหมวดหมู่และส่วนขยายคลาส ฉันเชื่อว่าทั้งสองใช้เพื่อเพิ่มวิธีการที่กำหนดเองในคลาสที่มีอยู่ ใครบางคนสามารถให้ความสำคัญกับเรื่องนี้ได้หรือไม่? การตรวจสอบด้วยรหัสจะได้รับการชื่นชมอย่างมาก
คำตอบ:
หมวดหมู่คือวิธีการเพิ่มเมธอดในคลาสที่มีอยู่ โดยปกติจะอยู่ในไฟล์ที่เรียกว่า "Class + CategoryName.h" เช่น "NSView + CustomAdditions.h" (และ. m แน่นอน)
ส่วนขยายคลาสเป็นหมวดหมู่ยกเว้นความแตกต่างหลัก 2 ประการ:
หมวดหมู่ไม่มีชื่อ มีการประกาศดังนี้:
@ อินเทอร์เฟซ SomeClass ()
- (void) anAdditionalMethod;
@end
การนำส่วนขยายไปใช้งานต้องอยู่ในบล็อก @implementation หลักของไฟล์
เป็นเรื่องปกติที่จะเห็นส่วนขยายคลาสที่ด้านบนของไฟล์. m ที่ประกาศวิธีการเพิ่มเติมในคลาสซึ่งจะถูกนำไปใช้ด้านล่างในส่วน @implementation หลักของคลาส นี่เป็นวิธีประกาศเมธอด "หลอกส่วนตัว" (หลอกส่วนตัวเพราะไม่ได้เป็นส่วนตัวจริง ๆ ไม่ใช่แค่เปิดเผยภายนอก)
=> ใน Objective C เมื่อคุณต้องการเพิ่มฟังก์ชันการทำงานเพิ่มเติมให้กับคลาสที่ไม่มีการสืบทอดคุณเพียงแค่ใช้หมวดหมู่สำหรับมัน
=> มาพร้อมกับไฟล์. hและ. mของตัวเอง
=> Category
ใช้เพื่อเพิ่มวิธีการใหม่ไม่ใช่คุณสมบัติ
-> In Objective C, when you want to make behaviour of some property private you use class extension.
-> it comes with **.h** file only.
-> mainly for properties.
หมายเหตุ: เมื่อเราเพิ่มไฟล์ใหม่และเลือกตัวเลือกของวัตถุประสงค์ c ประเภทจะแสดงหมวดหมู่และ "หมวดหมู่ใน" ไม่ใช่ "คลาสย่อยของ" ดังนั้นจึงแสดงเป็น
@interface className (categoryName)
@end
- คุณจะได้รับสองไฟล์. hและ. m พร้อมชื่อไฟล์เป็น ( className + categoryName.hและclassName + categoryName.m )
และในกรณีขยายคุณจะได้รับ
@interface className()
@end
- คุณจะได้รับไฟล์เดียวที่มีชื่อเป็นclassName_extensionName.h
หมวดหมู่เป็นวิธีการเพิ่มวิธีการลงในคลาสไม่ว่าจะมีซอร์สโค้ดหรือไม่ซึ่งหมายความว่าคุณสามารถเพิ่มหมวดหมู่ให้กับคลาสพื้นฐานเช่นNSString
และในคลาสแบบกำหนดเอง
สามารถเพิ่มส่วนขยายลงในคลาสที่มีซอร์สโค้ดได้เท่านั้นเนื่องจากคอมไพเลอร์รวบรวมซอร์สโค้ดและส่วนขยายในเวลาเดียวกัน
เราสามารถเพิ่มตัวแปรอินสแตนซ์และคุณสมบัติพิเศษในส่วนขยายคลาสได้ แต่ไม่สามารถเพิ่มในหมวดหมู่ได้
ตัวแปรและวิธีการใด ๆ ภายในส่วนขยายจะไม่สามารถเข้าถึงคลาสที่สืบทอดมาได้
หมวดหมู่และส่วนขยายโดยทั่วไปสร้างขึ้นเพื่อจัดการฐานรหัสขนาดใหญ่ แต่หมวดหมู่เป็นวิธีการขยายคลาส API ในไฟล์ต้นฉบับหลายไฟล์ในขณะที่ส่วนขยายเป็นวิธีการเพิ่มวิธีการที่จำเป็นนอกไฟล์อินเทอร์เฟซหลัก
ใช้หมวดหมู่เมื่อคุณต้องแบ่งรหัสคลาสเดียวกันออกเป็นไฟล์ต้นฉบับที่แตกต่างกันตามฟังก์ชันการทำงานที่แตกต่างกันและส่วนขยายเมื่อคุณต้องการเพิ่มวิธีการที่จำเป็นบางอย่างในคลาสที่มีอยู่นอกไฟล์อินเทอร์เฟซหลัก นอกจากนี้เมื่อคุณต้องการแก้ไขตัวแปรอินสแตนซ์ที่ประกาศต่อสาธารณะในคลาสตัวอย่างเช่นอ่านอย่างเดียวเพื่ออ่านเขียนคุณสามารถประกาศอีกครั้งในส่วนขยาย
ส่วนขยาย : เพื่อทำให้วิธีการเป็นส่วนตัวและเพื่อเพิ่มคุณสมบัติของคลาสที่กำหนดเองของเราเองไม่ใช่ของคลาส Apple
หมวดหมู่ : เพื่อเพิ่มวิธีการอื่น ๆ NSString
ในชั้นเรียนที่มีอยู่ไม่ได้ทรัพย์สินก็สามารถนำมาใช้สำหรับทั้งชั้นเองและชั้นแอปเปิ้ลเช่น
เรายังสามารถมีคุณสมบัติโดยใช้ชุดคุณสมบัติที่เกี่ยวข้องในคลาสประเภท
@interface SomeClass (Private)
@property (nonatomic, assign) id newProperty;
@end
NSString * const kNewPropertyKey = @"kNewPropertyKey";
@implementation SomeClass (Private)
@dynamic newProperty;
- (void)setNewProperty:(id)aObject
{
objc_setAssociatedObject(self, kNewPropertyKey, aObject, OBJC_ASSOCIATION_ASSIGN);
}
- (id)newProperty
{
return objc_getAssociatedObject(self, kNewPropertyKey);
}
@end
อ้างอิง: http://inchoo.net/dev-talk/ios-development/how-to-add-a-property-via-class-category/
@interface SomeClass ()
- (void) anAdditionalMethod;
@end
ผมว่ามันไม่ใช่วิธีประกาศ Category หมวดหมู่ต้องมีชื่อ
@interface SomeClass (XYZ)
- (void) anAdditionalMethod;
@end
ตัวอย่างเช่น
@interface NSMutableArray (NSMutableArrayCreation)
+ (id)arrayWithCapacity:(NSUInteger)numItems;
- (id)initWithCapacity:(NSUInteger)numItems;
@end
ประกาศสำหรับ NSMutableArray โดย Apple
ส่วนขยาย ios คล้ายกับ c #, java abstract class หรือ interface
ios category คล้ายกับ c #, java class extension
หมวดหมู่
หมวดหมู่ถูกใช้เมื่อคุณสร้างไฟล์ที่มีเมธอดจำนวนมากดังนั้นจึงให้ความสะดวกแก่คุณในการแบ่งคลาสเดียวออกเป็นโมดูลต่างๆนอกจากนี้หากมีการเปลี่ยนแปลงใด ๆ กับหมวดหมู่คอมไพเลอร์จะไม่เสียเวลาในการคอมไพล์โปรเจ็กต์ทั้งหมด หมวดหมู่ไม่สามารถเพิ่มตัวแปรหรือคุณสมบัติใหม่และค้นหาได้ไม่เกินคลาสพาเรนต์คุณสามารถแทนที่เมธอดในหมวดหมู่ได้ แต่ไม่ใช่ความคิดที่ดีเพราะไม่สามารถแทนที่เมธอดได้อีกนอกจากนี้โฟลว์ยังสามารถมีผลได้เนื่องจากหมวดหมู่ทั้งหมดมี ระดับลำดับชั้นเดียวกันและด้วยเหตุนี้สองประเภทที่อยู่ในคลาสหลักเดียวกันอาจมีอยู่ในขณะรันนอกจากนี้ยังสามารถสร้างวิธีการป้องกันโดยใช้หมวดหมู่
ส่วนขยาย
ส่วนขยายช่วยให้คุณสามารถแทนที่คุณสมบัติหรือเพิ่มคุณสมบัติใหม่ให้กับคลาสพาเรนต์ที่มีอยู่ได้เหมือนกับหมวดหมู่ที่ไม่มีชื่อและแสดงเป็นคลาส @interface () ไม่มีไฟล์. m อยู่และต้องใช้วิธีการที่ประกาศในส่วนขยาย ใน @implementation ของไฟล์พาเรนต์
ความช่วยเหลือเพิ่มเติมที่ลิงค์นี้
นี่คือความเข้าใจของฉัน:
ส่วนต่อขยายที่มักจะถูกนำมาใช้เพื่อเพิ่มคุณสมบัติพิเศษเพื่อตัวเองของเรา " ชั้นเอง " เราสามารถเพิ่มเมธอดส่วนตัวหรือคุณสมบัติเพื่อขยายอินเตอร์เฟสคลาสซึ่งสามารถใช้ได้ภายในการนำคลาสไปใช้
ส่วนขยายจะต้องเขียนภายในไฟล์เดียวกับคลาส ดังนั้นคุณจึงไม่สามารถเขียนส่วนขยายสำหรับประเภทที่กำหนดไว้ล่วงหน้าเช่น String, Float เป็นต้น
ในทางกลับกันหมวดหมู่สามารถใช้เพื่อเพิ่มวิธีการพิเศษให้กับคลาสที่มีอยู่ก่อน ตัวอย่างเราสามารถสร้างวิธีการของเราเองโดยการขยายคลาส String โปรดทราบว่าเราไม่สามารถสร้างคุณสมบัติพิเศษในหมวดหมู่ได้ ข้อได้เปรียบหลักของหมวดหมู่คือเราสามารถเขียนหมวดหมู่ในไฟล์อื่น ๆ นอกไฟล์ที่คลาสของคุณออกได้
นอกจากนี้ในขณะที่สร้างหมวดหมู่คุณควรตั้งชื่อให้ในวงเล็บ แต่สำหรับนามสกุลไม่จำเป็นต้องมีชื่อ ดังนั้นบางครั้งจึงเรียกว่าหมวดหมู่ที่ไม่ระบุตัวตน