การออกแบบ View ต่างๆ แล้วเก็บลง Nib file เป็นเรื่องที่ทำให้นักพัฒนาสะดวกในการออกแบบ UI มาก แต่หากใน Nib file นั้นมี Object ต่างๆ เยอะเกินไป หรือใน Nib file เดียว มี object ของทั้ง Application บรรจุอยู่ ก็จะทำให้เสียเวลาในการโหลด Nib file นานมาก เนื่องจากเมื่อ Nib file ถูกโหลด object ต่างๆที่อยู่ใน Nib file จะถูกโหลดให้มีชีวิตด้วย ดังนั้นเราควรแยก object ต่างๆใน Nib file ออกจากกันจากนั้นค่อยๆทยอยโหลดเข้ามาใช้เมื่อจำเป็นต้องใช้จริงๆเท่านั้น
ด้วยวิธีนี้ ทำให้เราจำเป็นต้องมี Nib file มากกว่า 1 file ใน Application Bundle ส่วนวิธีแยก Nib file ที่น่าจะได้รับความนิยมมากก็คือ 1 Nib file ต่อ 1 View Controller (สังเกตจากเวลาที่เรากำลังจะสร้าง file ที่เป็น Sub class ของ UIViewController ใน Xcode จะมี check box ให้เลือกว่าจะให้สร้าง Nib file ให้ด้วยเลยไหม)
แต่การแบ่งดังที่กล่าวมาอาจยังไม่เพียงพอ หากใน 1 View Controller นั้น มี object มากมายก่ายกองที่ถูกสร้างขึ้นใน Nib file ซึ่งก็แปลว่าแม้จะแยกออกมาเป็น Nib file เดียวต่อ View Controller แล้ว ก็อาจยังโหลดช้าอยู่ดี ดังนั้นใน entry นี้จะแนะนำวิธีการโหลด object จาก Nib file มากกว่า 1 Nib file มาใช้งานนั่นเอง
วิธีการดังนี้
สมมติว่าเรามี view controller subclass ชื่อ MainViewController ที่สร้างมาพร้อมกับ Nib file (check ในช่อง With XIB for user interface ตอนจะสร้างไฟล์) และในนั้นมี property ดังนี้
_toolbar จะเป็น Outlet ที่อยู่ใน Nib เดียวกันกับ MainViewController.xib ดังนั้นเมื่อเราโหลด MainViewController.xib ขึ้นมา เราสามารถอ้างถึง _toolbar เพื่อใช้งานได้เลยทันที
_complexView คือ UIView ที่เราไม่ได้สร้างให้มันอยู่ใน MainViewController.xib (ประกาศไว้เฉยๆ) ดังนั้นเมื่อเราโหลด MainViewController.xib ขึ้นมา เราจะไม่สามารถอ้างถึง _complexView เพื่อนำมาใช้งานได้ และเมื่อลอง log ออกมาดูดังนี้
จะพบว่าผลที่ได้คือ
ต่อไปเราจะสร้าง Nib file อีกไฟล์หนึ่ง ชื่อ AnotherNib.nib ในนั้นบรรจุ UIView ซึ่งมีหน้าตาดังนี้
ใน AnotherNib.xib ให้กำหนด File's Owner เป็น MainViewController และเมื่อ click ขวาที่ File's Owner จะพบ Outlets ที่เราได้ประกาศไว้ใน MainViewController.h ให้เราเชื่อมตัวแปร _complexView เข้าไปกับ View ใน AnotherNib.xib ซึ่ง View ตัวนี้แหละ ที่เรากำหนดจะโหลดมันเข้าไปใน MainViewController
หลังจากนั้น ทดลองโหลด View ใน AnotherNib.xib เข้ามาเก็บไว้ใน _complexView ได้ดัังนี้
จากโค๊ด เป็นการโหลด Nib file ที่ชื่อ AnotherNib ให้กับ self (object ที่เรียก method นี้ซึ่งก็คือ MainViewController) หลังจากโหลดเสร็จแล้ว _complexView จะมีชีวิตพร้อมใช้งานทันที และเมื่อ log ออกมาดูดังนี้
ก็จะเห็นว่า _complexView มีชีวิตแล้ว
ตัวอย่าง
Related Link from Roti
ด้วยวิธีนี้ ทำให้เราจำเป็นต้องมี Nib file มากกว่า 1 file ใน Application Bundle ส่วนวิธีแยก Nib file ที่น่าจะได้รับความนิยมมากก็คือ 1 Nib file ต่อ 1 View Controller (สังเกตจากเวลาที่เรากำลังจะสร้าง file ที่เป็น Sub class ของ UIViewController ใน Xcode จะมี check box ให้เลือกว่าจะให้สร้าง Nib file ให้ด้วยเลยไหม)
แต่การแบ่งดังที่กล่าวมาอาจยังไม่เพียงพอ หากใน 1 View Controller นั้น มี object มากมายก่ายกองที่ถูกสร้างขึ้นใน Nib file ซึ่งก็แปลว่าแม้จะแยกออกมาเป็น Nib file เดียวต่อ View Controller แล้ว ก็อาจยังโหลดช้าอยู่ดี ดังนั้นใน entry นี้จะแนะนำวิธีการโหลด object จาก Nib file มากกว่า 1 Nib file มาใช้งานนั่นเอง
วิธีการดังนี้
สมมติว่าเรามี view controller subclass ชื่อ MainViewController ที่สร้างมาพร้อมกับ Nib file (check ในช่อง With XIB for user interface ตอนจะสร้างไฟล์) และในนั้นมี property ดังนี้
@interface MainViewController : UIViewController {
IBOutlet UIToolbar *_toolbar;
IBOutlet UIView *_complexView;
}
_toolbar จะเป็น Outlet ที่อยู่ใน Nib เดียวกันกับ MainViewController.xib ดังนั้นเมื่อเราโหลด MainViewController.xib ขึ้นมา เราสามารถอ้างถึง _toolbar เพื่อใช้งานได้เลยทันที
_complexView คือ UIView ที่เราไม่ได้สร้างให้มันอยู่ใน MainViewController.xib (ประกาศไว้เฉยๆ) ดังนั้นเมื่อเราโหลด MainViewController.xib ขึ้นมา เราจะไม่สามารถอ้างถึง _complexView เพื่อนำมาใช้งานได้ และเมื่อลอง log ออกมาดูดังนี้
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"MainViewController - viewDidLoad: complexView = %@", _complexView);
}
จะพบว่าผลที่ได้คือ
MainViewController - viewDidLoad: complexView = (null)
ต่อไปเราจะสร้าง Nib file อีกไฟล์หนึ่ง ชื่อ AnotherNib.nib ในนั้นบรรจุ UIView ซึ่งมีหน้าตาดังนี้
ใน AnotherNib.xib ให้กำหนด File's Owner เป็น MainViewController และเมื่อ click ขวาที่ File's Owner จะพบ Outlets ที่เราได้ประกาศไว้ใน MainViewController.h ให้เราเชื่อมตัวแปร _complexView เข้าไปกับ View ใน AnotherNib.xib ซึ่ง View ตัวนี้แหละ ที่เรากำหนดจะโหลดมันเข้าไปใน MainViewController
หลังจากนั้น ทดลองโหลด View ใน AnotherNib.xib เข้ามาเก็บไว้ใน _complexView ได้ดัังนี้
[[NSBundle mainBundle] loadNibNamed: @"AnotherNib" owner: self options: nil];
จากโค๊ด เป็นการโหลด Nib file ที่ชื่อ AnotherNib ให้กับ self (object ที่เรียก method นี้ซึ่งก็คือ MainViewController) หลังจากโหลดเสร็จแล้ว _complexView จะมีชีวิตพร้อมใช้งานทันที และเมื่อ log ออกมาดูดังนี้
NSLog(@"MainViewController - viewDidLoad: complexView = %@", _complexView);
ก็จะเห็นว่า _complexView มีชีวิตแล้ว
MainViewController - viewDidLoad: complexView = <UIView: 0x391e830; frame = (0 250; 320 100); autoresize = RM+BM; layer = <CALayer: 0x3909410>>
ตัวอย่าง

