2010-11-02 3 views
5

Tương đương với java được đồng bộ hóa trong mục tiêu c là gì? Tôi muốn để có thể thực hiện phương pháp singleton tôi an toàn, vì vậy khi nó Bein gọi từ 2 chủ đề khác nhau, họ cố gắng sử dụng nó 1 bằng 1.Whats tương đương với đồng bộ trong Objective-C?

+(MyObject*) getSharedObject 
{ 
    if(!singleton) 
    { 
      singleton = [[MyObject alloc] init]; 
    } 
    return singleton; 
} 
+0

trùng lặp http://stackoverflow.com/questions/1215330/how-does-synchronized-lock-unlock-in-objective-c –

+1

Không hẳn là một bản sao, một câu hỏi có liên quan chắc chắn rồi. –

Trả lời

10

obj-C có đồng bộ xây dựng

-(MyObject*) getSharedObject 
{ 
@synchronized(something) 
{ 
    if(!singleton) 
    { 
      singleton = [[MyObject alloc] init]; 
    } 
    return singleton; 
} 
} 

trả về từ trong một khối được đồng bộ hóa, điều 'đúng'

+0

Chỉ cần một sửa chữa nhỏ, tôi nghĩ rằng OP muốn sử dụng phương pháp tĩnh – onmyway133

9

Câu trả lời của Joshua là đúng, nhưng yêu cầu bạn phải có đối tượng để đồng bộ hóa. Làm điều này cho một singleton có thể dẫn đến tất cả các loại điều kiện chủng tộc lẻ nếu bạn không cẩn thận. Các mô hình chuẩn cho một singleton là để khởi tạo nó trong +initialize, sử dụng dispatch_once, mà làm điều đúng đắn:

static MyObject *singleton = nil; 

+ (void)initialize { 
    static dispatch_once_t pred; 
    dispatch_once(&pred, ^{ singleton = [[MyObject alloc] init]; }); 
} 

- (MyObject&)getSharedObject 
{ 
    return singleton; 
} 
+2

Đồng bộ hóa trên lớp của singleton, sau đó không có điều kiện chủng tộc lẻ. – JeremyP

+1

Đây là kiểu được khuyến nghị bởi Apple. – Eonil

-1

Tôi đồng ý với cả hai câu trả lời. Nhưng nếu ý tưởng này là để nhanh chóng theo yêu cầu sau đó tôi muốn đi với đề nghị của Giô-suê với một sửa đổi nhỏ sử dụng kiểm tra lại-khóa:

if (!singleton) 
    @synchronized(something) 
     if (!singleton) 
     instantiate; 

Bằng cách này bạn tránh khóa không cần thiết sau khi đối tượng đã được khởi tạo.

+2

Có rất nhiều điều kiện chạy đua tinh tế liên quan đến việc kiểm tra khóa kép. Tôi sẽ tránh nó. – JeremyP

+0

Đó không phải là cuộc bỏ phiếu của tôi btw – JeremyP

+0

Tôi đánh giá cao phản hồi của bạn JeremyP, tôi thừa nhận rằng tôi không biết các vấn đề đó. Tuy nhiên tôi vẫn nghĩ rằng nó có giá trị nỗ lực để hiểu những vấn đề và làm cho nó ngay đặc biệt là nếu mã này sẽ có lưu lượng truy cập cao, nó sẽ là quá xấu để cố ý thêm một điểm có thể tranh chấp. Nhiều đánh giá cao! – fhj

8

Để đồng bộ hóa việc tạo singleton, bạn nên sử dụng lớp của singleton làm đối tượng để đồng bộ hóa. Đây là mô hình thông thường của tôi:

+(MyObject*) singleton 
{ 
    static MyObject* singleton = nil; 
    @synchronized([MyObject class]) 
    { 
     if(singleton == nil) 
     { 
      singleton = [[MyObject alloc] init]; 
     } 
    } 
    return singleton; 
} 

điểm cần lưu ý:

  • Tôi đã thực hiện nó một phương pháp học. Bạn không thực sự phải làm, nó sẽ hoạt động như một phương thức thể hiện.

  • Thông thường trong các phương thức lớp học khi tham chiếu đến lớp học, bạn sẽ sử dụng self (hoặc [self class] trong các phương pháp ví dụ). Tuy nhiên, điều đó sẽ sai ở đây vì các lớp con sẽ đồng bộ hóa bằng cách sử dụng một đối tượng khác vào lớp MyObject.

  • Tôi đã đặt trả lại bên ngoài khối @synchronize. Nó là hoàn toàn OK để trở về từ bên trong khối, nhưng nếu bạn làm, bạn nhận được một cảnh báo phân tích tĩnh giả mạo tĩnh nói rằng phương pháp có thể không trả về một giá trị.


Sửa

Các mô hình trên là từ lâu đã lỗi thời. Tốt nhất là nên sử dụng các mô hình dispatch_once

+(MyObject*) singleton 
{ 
    static dispatch_once_t onceToken; 
    static MyObject* singleton = nil; 

    dispatch_once (&onceToken, ^{ 
     singleton = [[MyObject alloc] init]; 
    }); 
    return singleton; 
} 
+2

tĩnh MyObject * singleton = nil; Điều này không đặt đối tượng đơn lẻ thành không, và khởi tạo lại nó mỗi khi phương thức được gọi? – aryaxt

+0

IIRC, trong ObjC, về cơ bản tĩnh có nghĩa là "chỉ một trong số này tồn tại" do đó, nó chỉ được khởi tạo một lần. – JimR

+3

Tĩnh trong Obj-C cũng giống như trong C, nghĩa là dòng đó sẽ chỉ được khởi tạo một lần –