2015-09-18 38 views
7

Tôi đã cố gắng triển khai mẫu CQRS trong ứng dụng ios nhanh và tôi thấy hành vi kỳ lạ.Swift - vấn đề generics gây rò rỉ bộ nhớ

lớp cốt lõi:

class Query<T> {} 

class QueryHandler<TResult, TQuery:Query<TResult>> { 

    func execute(query: TQuery, callback: (result: TResult) -> Void) { 
    } 
} 

lớp Thực hiện: sử dụng

class GetRandomStringsQuery: Query<[String]> { 
internal var prefix:String 

init(prefix: String) { 
    self.prefix = prefix 
    } 
} 

class GetRandomStringsQueryHandler: QueryHandler<[String], GetRandomStringsQuery> { 

    override func execute(query: GetRandomStringsQuery, callback: (result: [String]) -> Void) { 
     var result = [String]() 

     for var i = 0; i < 100; i++ { 
      result.append("[\(i)]: \(query.prefix)") 
     } 

     callback(result: result) 
    } 
} 

Ví dụ:

@IBAction func generateMemoryLeak(sender: AnyObject) { 
     let query = GetRandomStringsQuery(prefix: "leak leak leak :(") 

     let queryHandler = GetRandomStringsQueryHandler() 

     queryHandler.execute(query) { (result) -> Void in 
      print("total records: \(result.count)") 
     } 
} 

Trong callback chúng tôi sẽ nhận được 100 phần tử trong mảng. Tại thời gian chạy nó có vẻ như tham chiếu bị mất và giá trị là không rõ. Công cụ dành cho nhà phát triển iOS phát hiện rò rỉ bộ nhớ.

Ứng dụng quan trọng là khi chúng tôi xóa siêu lớp khỏi GetRandomStringsQueryHandler và loại bỏ công cụ sửa đổi "ghi đè" khỏi chức năng thực thi sẽ không có rò rỉ bộ nhớ và ứng dụng sẽ hoạt động tốt!

Ai đó có thể giải thích hành vi này? Đó là lỗi của tôi hoặc vấn đề nhanh chóng?

Tôi đang sử dụng verion cuối cùng của Xcode với swift 2.

+0

Làm thế nào để bạn xác định có một rò rỉ bộ nhớ? Bạn đang chạy trên một thiết bị thực đang hết bộ nhớ và gặp sự cố? Hoặc chỉ xác nhận với các công cụ? Và khi bạn xác nhận trong các công cụ, bạn có đang sử dụng thiết bị thực hoặc trình mô phỏng không? Và cả hai cách, bộ nhớ nào đang được báo cáo là bị rò rỉ? – nhgrif

+0

Ngay bây giờ khi tôi chạy ứng dụng tôi nhận được ngoại lệ: EXC_BAD_ACCESS trong libswiftCore.dylib'_swift_release_ (swift :: HeapObject *): Trong kết nối với thiết bị tôi đang sử dụng trình mô phỏng. – razor118

+0

Đó là một chút khác biệt so với rò rỉ bộ nhớ và có lẽ nên được thêm vào câu hỏi của bạn. – nhgrif

Trả lời

2

Câu hỏi thú vị! Tôi dán mã của bạn vào sân chơi và quản lý để sao chép lỗi bạn gặp phải. Tôi đã cố gắng để tinh chỉnh mã nhưng không thành công để có được các generics để làm việc. Thay vào đó, tôi kết thúc viết lại mã bằng cách sử dụng các giao thức để thể hiện các ràng buộc.

giao thức cốt lõi:

protocol QueryType { 
    typealias ResultType 
} 

protocol QueryHandler { 
    typealias Query: QueryType 
    func execute(query: Self.Query, callback: (result: Self.Query.ResultType) -> Void) 
} 

lớp Phù hợp:

class GetRandomStringsQuery: QueryType { 
    typealias ResultType = [String] 

    internal var prefix:String 

    init(prefix: String) { 
     self.prefix = prefix 
    } 
} 


class GetRandomStringsQueryHandler: QueryHandler { 

    func execute(query: GetRandomStringsQuery, callback: (result: [String]) -> Void) { 
     var result = [String]() 

     for var i = 0; i < 100; i++ { 
      result.append("[\(i)]: \(query.prefix)") 
     } 

     callback(result: result) 
    } 

} 

Mã số điện thoại:

let query = GetRandomStringsQuery(prefix: "leak leak leak :(") 

let queryHandler = GetRandomStringsQueryHandler() 

queryHandler.execute(query) { (result) -> Void in 
    print("total records: \(result.count)") 
} 
+0

+1 để tái cấu trúc với các giao thức và liên kết các loại truy vấn và trình xử lý liên quan. chỉ có điều là tôi nghĩ rằng bạn quên để xác định typealias của bạn trên GetRandomStringsQueryHandler –

+0

Tôi đoán trình biên dịch có thể suy ra rằng dựa trên những gì tôi đã thông qua như một đối số cho phương thức thực hiện.Nếu không, nó sẽ gây ra vấn đề với sự phù hợp của giao thức. –

+0

Xin chào, cảm ơn bạn đã tạo giao thức thay thế cho vấn đề đó. Tôi hy vọng rằng chung chung sẽ được cố định càng sớm càng tốt. – razor118