เป็นไปได้ไหมที่จะสร้างอินสแตนซ์ของคลาสตามชื่อ สิ่งที่ต้องการ:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
ฉันไม่รู้ว่ามันเป็นไปได้หรือไม่ใน objective-c แต่ดูเหมือนว่าจะเป็น
เป็นไปได้ไหมที่จะสร้างอินสแตนซ์ของคลาสตามชื่อ สิ่งที่ต้องการ:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
ฉันไม่รู้ว่ามันเป็นไปได้หรือไม่ใน objective-c แต่ดูเหมือนว่าจะเป็น
คำตอบ:
id object = [[NSClassFromString(@"NameofClass") alloc] init];
NSClassFromString()
เสี่ยงต่อการพิมพ์ชื่อคลาสผิดหรือใช้คลาสที่ไม่มีอยู่ คุณจะไม่พบจนกว่ารันไทม์หากคุณทำผิดพลาด แต่ถ้าคุณใช้ชนิด Object-c ในตัวClass
เพื่อสร้างตัวแปรคอมไพลเลอร์จะตรวจสอบว่าคลาสนั้นมีอยู่จริง
ตัวอย่างเช่นใน.h
:
@property Class NameOfClass;
จากนั้นใน.m
:
id object = [[NameOfClass alloc] init];
หากคุณพิมพ์ชื่อคลาสผิดหรือหากไม่มีอยู่คุณจะได้รับข้อผิดพลาดในขณะคอมไพล์ ฉันคิดว่านี่เป็นรหัสที่สะอาดกว่า
หากคุณกำลังทำงานกับ Objective-C โดยไม่ต้องNeXTstep
( OS X
, iOS
, GNUstep
ระบบ ฯลฯ ) หรือคุณเพียงแค่คิดว่าวิธีนี้คือการทำความสะอาดแล้วคุณสามารถใช้ประโยชน์จากObjective-C ภาษา runtime library ของ API ภายใต้Objective-C 2.0
:
#import <objc/runtime.h>
//Declaration in the above named file
id objc_getClass(const char* name);
//Usage
id c = objc_getClass("Object");
[ [ c alloc ] free ];
ภายใต้ Objective-C (1.0 หรือเวอร์ชันที่ไม่มีชื่อ) คุณจะใช้สิ่งต่อไปนี้:
#import <objc/objc-api.h>
//Declaration within the above named file
Class objc_get_class( const char* name);
//Usage
Class cls = objc_get_class( "Test" );
id obj = class_create_instance( cls );
[ obj free ];
ฉันยังไม่ได้ทดสอบ1.0
เวอร์ชัน แต่ฉันได้ใช้2.0
ฟังก์ชันในโค้ดที่อยู่ในระหว่างการผลิต โดยส่วนตัวแล้วฉันเชื่อว่าการใช้2.0
ฟังก์ชันนี้จะสะอาดกว่าถ้ามีมากกว่าฟังก์ชัน NS เนื่องจากใช้พื้นที่น้อยกว่า: the length of the name in bytes + 1 ( null terminator )
สำหรับ 2.0 API เทียบกับthe sum of two pointers (isa, cstring)
a size_t length (cstring_length)
และlength of the string in bytes + 1
สำหรับNeXTSTEP
API
@interface Magic : NSObject
+ (id)createInstanceOfClass:(Class)classe;
@end
@implementation Magic
+ (id)createInstanceOfClass:(Class)classe
{
return [[classe alloc] init];
}
@end
จากนั้นจะใช้มัน:
Car *car = [Magic createInstanceOfClass:[Car class]];
[car engineTurnOn];