2017-04-13 17 views
5

Tôi có một singleton lớp như vậy:Làm thế nào để tạo một chủ đề cá thể Swift Class Singleton an toàn?

class Database { 
    static let instance:Database = Database() 
    private var db: Connection? 

    private init(){ 
     do { 
     db = try Connection("\(path)/SalesPresenterDatabase.sqlite3") 
     }catch{print(error)} 
    } 
} 

Bây giờ tôi truy cập lớp này sử dụng Database.instance.xxxxxx để thực hiện một chức năng trong lớp. Tuy nhiên, khi tôi truy cập cá thể từ một luồng khác, nó ném các kết quả kỳ quái như thể nó đang cố gắng tạo một cá thể khác. Tôi có nên tham chiếu cá thể trong cùng một chuỗi không?

Để làm rõ những kết quả kỳ lạ hiển thị cơ sở dữ liệu I/o sai lầm vì của hai trường hợp cố gắng để truy cập vào db cùng một lúc

Cập nhật
xin vui lòng xem câu hỏi này để biết thêm về các mã cơ sở dữ liệu: Using transactions to insert is throwing errors Sqlite.swift

+6

Tạo singleton nhanh là chủ đề an toàn. Điều này không có nghĩa là các hàm mà bạn gọi trong cá thể singleton sẽ là chủ đề an toàn. Bạn cần phải sử dụng một cái gì đó như semaphore, một hàng đợi công văn nối tiếp hoặc hàng đợi hoạt động nếu bạn cần làm cho thread chức năng an toàn – Paulw11

+0

'Tuy nhiên khi tôi truy cập cá thể từ một chủ đề khác, nó ném kết quả kỳ quái như thể nó đang cố tạo một thể hiện khác. đừng nghĩ vậy, với định nghĩa hiện tại của lớp 'Database', bạn ** không thể tạo ra 2 thể hiện. Tuy nhiên có thể có thêm mã vào lớp mà bạn không hiển thị. BTW: một lần tinh chỉnh cuối cùng cho lớp của bạn: bạn nên khai báo nó là 'final' để ngăn chặn phân lớp phụ. –

+0

Mã bổ sung trong lớp hiển thị hàm ** addRow **. Hàm này được gọi trong khối hoàn thành alamofire, sau đó ném lỗi mà nó không thể chèn dữ liệu. Điều thú vị là nếu tôi loại bỏ tất cả các cuộc gọi đến Database.instance của tôi. Singleton và để cho các bit có vấn đề của mã chạy nó đầu tiên, nó sẽ làm việc tốt ... –

Trả lời

5
class var shareInstance: ClassName { 

    get { 
     struct Static { 
      static var instance: ClassName? = nil 
      static var token: dispatch_once_t = 0 
     } 
     dispatch_once(&Static.token, { 
      Static.instance = ClassName() 
     }) 
     return Static.instance! 
    } 
} 

SỬ DỤNG: hãy đối tượng: ClassName = ClassName.shareInstance

Swift 3.0

class ClassName { 
    static let sharedInstance: ClassName = { ClassName()}() 
} 

SỬ DỤNG: hãy đối tượng: ClassName = ClassName.shareInstance

+0

Tôi đang sử dụng swift3 để tùy chọn dispatch_once_t không có sẵn cho tôi .... –

1

Trong Swift 3.0 thêm một init tin để ngăn chặn người khác sử dụng mặc định() khởi tạo.

class ClassName { 
    static let sharedInstance = ClassName() 
    private init() {} //This prevents others from using the default '()' initializer for this class. 
} 
Các vấn đề liên quan