2009-06-14 38 views
69

Tôi mới vào Objective C và tôi đã không thể tìm ra nếu có tương đương với một constructor tĩnh trong ngôn ngữ, đó là một phương thức tĩnh trong một lớp sẽ tự động được gọi trước phiên bản đầu tiên của lớp như vậy được khởi tạo. Hoặc tôi có cần tự gọi mã Khởi tạo không?Hàm tạo tĩnh tương đương trong Objective-C?

Cảm ơn

Trả lời

121

Phương pháp +initialize được gọi là tự động lần đầu tiên một lớp được sử dụng, trước khi bất kỳ phương thức lớp nào được sử dụng hoặc các phiên bản được tạo. Bạn không bao giờ nên tự gọi số +initialize.

Tôi cũng muốn vượt qua cùng một miếng ngon Tôi đã học được rằng có thể cắn bạn xuống đường: +initialize được thừa hưởng bởi lớp con, và cũng được gọi là cho mỗi lớp con mà không thực hiện một +initialize của riêng mình. Điều này có thể đặc biệt có vấn đề nếu bạn ngây thơ thực hiện khởi tạo singleton trong +initialize. Giải pháp là để kiểm tra kiểu của biến lớp học như vậy:

+ (void) initialize { 
    if (self == [MyParentClass class]) { 
    // Once-only initializion 
    } 
    // Initialization for this class and any subclasses 
} 

Tất cả các lớp học xuống từ NSObject có cả +class-class phương pháp mà trả lại đối tượng Class. Vì chỉ có một đối tượng Lớp cho mỗi lớp, nên chúng tôi muốn kiểm tra sự bình đẳng với toán tử ==. Bạn có thể sử dụng điều này để lọc những gì sẽ xảy ra chỉ một lần, so với một lần cho mỗi lớp riêng biệt trong một hệ thống phân cấp (có thể chưa tồn tại) bên dưới một lớp đã cho.

Trên một chủ đề tiếp tuyến, nó có giá trị tìm hiểu về các phương pháp liên quan sau đây, nếu bạn chưa sẵn sàng:


Edit: Check-out bài này bằng cách @bbum giải thích thêm về +initialize: http://www.friday.com/bbum/2009/09/06/iniailize-can-be-executed-multiple-times-load-not-so-much/

Ngoài ra, Mike Ash đã viết một thoải mái chi tiết Thứ Sáu Q & Một về +initialize+load phương pháp: https://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html

+5

"if ([self class] == [MyParentClass class])" '[self class]' là dự phòng ở đây. bạn chỉ có thể nói 'if (self == [MyParentClass class])' – user102008

+1

Cảm ơn bạn! Tidbit của bạn đã trả lời câu hỏi của tôi về lý do tại sao một trình khởi tạo tĩnh cụ thể đã được gọi hai lần. –

51

Có phương pháp +initialize lớp đó sẽ được gọi trước khi một lớp được sử dụng.

+0

Cảm ơn bạn, đó chính xác là những gì tôi đang tìm kiếm, nhưng tôi đã tìm kiếm để "tĩnh init", "tĩnh initializer", vv và không tìm thấy nó. –

+8

Trong hầu hết mọi trường hợp, trong Java bạn muốn nói "tĩnh", bạn nói "class" trong Objective-C. – Chuck

10

Một chút phụ lục cho chủ đề này:

Có một cách khác để tạo 'hàm tạo tĩnh' i n obj-c, sử dụng một chỉ thị __attribute:

// prototype 
void myStaticInitMethod(void); 

__attribute__((constructor)) 
void myStaticInitMethod() 
{ 
    // code here will be called as soon as the binary is loaded into memory 
    // before any other code has a chance to call +initialize. 
    // useful for a situation where you have a struct that must be 
    // initialized before any calls are made to the class, 
    // as they would be used as parameters to the constructors. 
    // e.g. 
    myStructDef.myVariable1 = "some C string"; 
    myStructDef.myFlag1 = TRUE; 

    // so when the user calls the code [MyClass createClassFromStruct:myStructDef], 
    // myStructDef is not junk values. 
} 
+2

+ tải sẽ làm điều tương tự và trông đồng bộ hơn với mô hình Objective-C –

+0

@Grady Nope, tôi liệt kê một tình huống cụ thể trong bài đăng + tải không tương đương. –

+0

+ khởi tạo sẽ khác, nhưng + tải phải giống nhau không? –

Các vấn đề liên quan