2011-01-05 39 views
5

Tôi có một Singleton thiết lập như thế này:Sử dụng Singleton trong giao diện Builder?

static Universe *instance; 

+ (Universe *)instance { return instance; } 

+ (void)initialize 
{ 
    static BOOL initialized = NO; 
    if(!initialized) 
    { 
     initialized = YES; 
     instance = [[Universe alloc] init]; 
    } 
} 

- (id) init 
{ 
    self = [super init]; 
    if (self != nil) { 
     self.showHistory = YES; 
    } 
    return self; 
} 

nhưng bây giờ tôi nhận ra rằng tôi muốn nhanh chóng nó từ giao diện Builder. Tôi đã nghĩ đến việc chỉ cần cắt phương thức init như vậy

if (instance) 
     return instance; 

đây có phải là một ý tưởng tồi không? Tôi muốn IB chọn trường hợp đã được tạo trong phương thức +initialize.

Trả lời

6

Điều này có thể được thực hiện. Có một phần về nó trong Mẫu thiết kế ca cao bởi Buck và Yachtman.

Trong trường hợp của bạn, bạn có thể làm một cái gì đó dọc theo dòng:

static Universe *instance; 

+ (Universe *)instance { return instance; } 

+ (id)hiddenAlloc 
{ 
    return [super alloc]; 
} 

+ (id)alloc 
{ 
    return [[self instance] retain]; 
} 

+ (void)initialize 
{ 
    static BOOL initialized = NO; 
    if(!initialized) 
    { 
     initialized = YES; 
     instance = [[Universe hiddenAlloc] init]; 
    } 
} 

- (id)init 
{ 
    if(instance==nil) // allow only to be called once 
    { 
    // your normal initialization here 
    } 
    return self; 
} 

Các ngòi đang tải sau đó sẽ chọn một cách chính xác lên singleton qua cuộc gọi của nó để [[Universe alloc] init], và bạn vẫn có thể sử dụng instance trong mã của bạn như trước.

Cuốn sách này có chi tiết hơn và khuyến cáo thực hiện newallocWithZone (cả đơn giản là return [self alloc];), cộng với cuống lỗi báo cáo để bắt copyWithZonemutableCopyWithZone nỗ lực cho biện pháp tốt.

+1

Đây là những gì tôi đã làm để triển khai phiên bản plugin của một số mã máy khách nối mạng ban đầu trong ứng dụng Cocoa. Một đồng nghiệp muốn nó trong một plugin vì vậy tôi đã đi các tuyến đường singleton vì vậy chỉ có một ví dụ thực tế của khách hàng mạng (nội bộ). – ExitToShell

+0

@invariant, tuyệt vời trả lời các loại mà làm cho tôi vui mừng khi đã đặt câu hỏi và không chỉ loại bỏ nó như câm. –

+2

'+ alloc' sẽ trả về' [[self instance] retain] ', vì' alloc' trả về một đối tượng sở hữu. –

1

Điều đó sẽ bị rò rỉ. Bạn có thể thoát khỏi nó nếu bạn thay đổi nó thành:

if(instance) { 
    [self release]; 
    return instance; 
} 

nhưng nó vẫn có mùi một chút với tôi. Tôi tò mò bạn sử dụng những gì cho những người độc thân trong IB; Tôi nghi ngờ tôi sẽ tránh cấu trúc này trong mã của tôi.

+0

Xin chào Seamus, vâng, mã không hoạt động do "Bộ mã hóa này yêu cầu các đối tượng thay thế phải được trả về từ initWithCoder" ... dù sao, tôi sẽ kiểm tra Đối tượng bên ngoài trong IB. Vấn đề là tôi sử dụng một trung tâm Singleton như một cây cầu cho tất cả các phần của ứng dụng ... vì vậy mỗi phần đăng ký chính nó với singleton. Nhưng sau đó tôi nghĩ, tại sao không dây một số trong số họ? –

+0

http://stackoverflow.com/questions/350861/what-bad-practice-do-you-do-and-why/350900#350900 –

+1

^^ yêu chuỗi lời thú nhận đó :) –

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