การเตรียมการสัมภาษณ์ iOS 5 — Singletons
รูปแบบ singleton เป็นรูปแบบการออกแบบที่รับรองว่าคลาสมีอินสแตนซ์เดียวและให้จุดเข้าถึงส่วนกลางสำหรับอินสแตนซ์นั้น สิ่งนี้มีประโยชน์เมื่อคลาสต้องแชร์ข้ามส่วนต่างๆ ของแอพ แต่การสร้างอินสแตนซ์ของคลาสหลายอินสแตนซ์นั้นไม่เหมาะสมหรือไม่เป็นที่ต้องการ ใน iOS รูปแบบซิงเกิลเป็นรูปแบบการออกแบบที่ใช้กันทั่วไป
คำถามสัมภาษณ์
- Singleton คืออะไรและใช้ในการพัฒนา iOS อย่างไร
- คุณสามารถอธิบายรูปแบบการออกแบบ Singleton และข้อดีของมันได้หรือไม่?
- วิธีใดบ้างที่เป็นไปได้ในการป้องกัน Singleton หลายอินสแตนซ์ในสภาพแวดล้อมแบบมัลติเธรด
- คุณยกตัวอย่างได้ไหมว่าเมื่อใดที่คุณจะใช้ Singleton ในแอป iOS ของคุณ
- คุณทดสอบ Singleton ใน iOS ได้อย่างไร
ข้อกังวลอย่างหนึ่งเกี่ยวกับ singletons คือบ่อยครั้งที่ไม่ปลอดภัยต่อเธรด มักใช้จากคอนโทรลเลอร์หลายตัวที่เข้าถึงอินสแตนซ์ซิงเกิลพร้อมกัน
คุณต้องพิจารณาสองสิ่งเมื่อสร้างซิงเกิลตัน
- ควรสร้างอินสแตนซ์ในลักษณะที่ปลอดภัยของเธรด
- คุณควรทำเครื่องหมายเมธอด init ของคลาสเป็นแบบส่วนตัวเพื่อป้องกันไม่ให้สร้างอินสแตนซ์เพิ่มเติม
- ระหว่างการเริ่มต้นของอินสแตนซ์ซิงเกิล
- ระหว่างการอ่านและเขียนอินสแตนซ์
ในการใช้รูปแบบ singleton ใน Swift คลาสที่ต้องการเป็น singleton จะถูกกำหนดด้วยstatic
คีย์เวิร์ด ซึ่งบ่งชี้ว่าคลาสนั้นมีเพียงอินสแตนซ์เดียวเท่านั้น ตัวแปรสแตติกถูกใช้เพื่อจัดเก็บอินสแตนซ์ของคลาส และเมธอดสแตติกถูกใช้เพื่อเข้าถึงอินสแตนซ์ นี่คือตัวอย่างของคลาส singleton ใน Swift
class Singleton {
// Swift guarantees initialization is atomic
// Swift treats the code performing initialization as a critical section
static let shared = Singleton()
// prevents the creation of additional instances of the class.
private init() {}
}
let singleton = Singleton.shared
@implementation MySingleton
// Lazy initializer
+ (instancetype)sharedInstance {
static dispatch_once_t once;
static id sharedInstance;
// The token ensures that init is executed only once in thread safety manner
dispatch_once(&once, ^{
_sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
// Prevent creating new instance of the singleton
- (instancetype)init __attribute__((unavailable("Use +[MyClass sharedInstance] instead")));
+ (instancetype)new __attribute__((unavailable("Use +[MyClass sharedInstance] instead")));
@end
ข้อดี
- ตรวจสอบให้แน่ใจว่าสร้างเพียงอินสแตนซ์เดียวของคลาส ซึ่งสามารถช่วยประหยัดหน่วยความจำและปรับปรุงประสิทธิภาพ
- ให้จุดเข้าถึงส่วนกลางสำหรับอินสแตนซ์ของคลาส ซึ่งทำให้ง่ายต่อการใช้งานในโค้ดของคุณ
- อาจมีประโยชน์สำหรับการนำทรัพยากรที่ใช้ร่วมกันไปใช้ เช่น ฐานข้อมูลหรือการเชื่อมต่อเครือข่าย ซึ่งจำเป็นต้องใช้ร่วมกันระหว่างส่วนต่างๆ ของรหัสของคุณ
- ทำให้โค้ดของคุณทดสอบและดีบักได้ยาก เนื่องจากโค้ดจะแนะนำสถานะส่วนกลางที่ใช้ร่วมกันระหว่างส่วนต่างๆ ของโค้ด
- ทำให้การสร้างหลายอินสแตนซ์ของคลาสเพื่อการทดสอบหรือวัตถุประสงค์อื่นทำได้ยาก
- สามารถนำไปสู่การต่อแน่นและละเมิดหลักการออกแบบเชิงวัตถุได้
- ไม่ใช่ตัวเลือกที่ดีสำหรับงานที่เกี่ยวข้องกับเซสชันของผู้ใช้ เนื่องจากคุณอาจต้องทำลายและสร้างซิงเกิลตันใหม่เมื่อผู้ใช้ออกจากระบบ
มีการรับประกัน 1 รายการต่อบัญชี (แทนที่จะรับประกัน 1 รายการต่อแอป) การเข้าถึงไม่ใช่ส่วนกลาง (คุณต้องมีเซสชันผู้ใช้) เช่นเดียวกับ singleton สร้างขึ้นอย่างเกียจคร้านในการเข้าถึงครั้งแรก อินสแตนซ์เดียวกันจะถูกส่งคืนในภายหลัง ตัวอย่างเช่น MyUserSession จะถูกสร้างขึ้นเมื่อผู้ใช้ที่ผ่านการรับรองความถูกต้องเริ่มเซสชัน ต้องแทรกลงในรหัสใด ๆ ที่มีข้อมูลผู้ใช้