2015-12-21 58 views
13

Chúng tôi đang cố gắng sử dụng các cấu trúc Swift nơi chúng tôi có thể. Chúng tôi cũng đang sử dụng RxSwift trong đó có phương pháp có đóng cửa. Khi chúng tôi có cấu trúc tạo ra một đóng có liên quan đến tự, tạo ra một strong reference cycle.Rò rỉ bộ nhớ cấu trúc Swift

import Foundation 
import RxSwift 

struct DoesItLeak { 

    var someState: String = "initial value" 
    var someVariable: Variable<String> = Variable("some stuff") 

    let bag = DisposeBag() 

    mutating func someFoo() { 

     someVariable.subscribeNext { person in 

      self.someState = "something" 
     } 
     .addDisposableTo(bag) 
    } 
} 

Làm cách nào để biết điều này? Nếu tôi tạo ra 100.000 đối tượng doesItLeak và gọi someFoo() trên mỗi người trong số họ, tôi tin rằng tôi có 100.000 đối tượng với chu kỳ tham chiếu mạnh mẽ. Nói cách khác, khi tôi loại bỏ mảng DoesItLeak chứa các đối tượng đó, các đối tượng vẫn nằm trong bộ nhớ. Nếu tôi không gọi someFoo(), không có vấn đề gì cả.

Biến là một lớp học. Vì vậy, tôi có thể thấy vấn đề bộ nhớ này bằng cách sử dụng phân bổ và lọc xcode của Instruments' trong Biến < String>

Filtering By Variable

enter image description here

Nếu tôi cố gắng sử dụng [tự yếu] chẳng hạn như trong sau đây, tôi gặp phải lỗi trình biên dịch:

someVariable.subscribeNext { [weak self] person in 

Lỗi trình biên dịch là "không thể áp dụng yếu cho loại không thuộc loại"

Trong mã thực/không phải mẫu, chúng tôi truy cập các phương thức và biến thông qua bản thân và đó là vấn đề về bộ nhớ.

Làm cách nào để giải quyết vấn đề bộ nhớ này trong khi vẫn giữ cấu trúc của DoesItLeak?

Cảm ơn sự giúp đỡ của bạn.

+1

Có thể nhấn mạnh vào việc sử dụng cấu trúc là vi phạm điều này ** Chọn giữa lớp học và cấu trúc ** hướng dẫn: "Rất hợp lý để mong đợi rằng các giá trị đóng gói sẽ được sao chép thay vì được tham chiếu khi bạn chỉ định hoặc chuyển xung quanh ví dụ về cấu trúc đó. " - https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html – finneycanhelp

+2

Tôi không nghĩ rằng bạn có một rò rỉ bộ nhớ - ít nhất không phải là một do việc đóng cửa bằng cách sử dụng tự để chỉ một cấu trúc. Từ những gì tôi có thể nói, khi bạn sử dụng self để chỉ một cấu trúc trong một bao đóng, chỉ đơn thuần là tạo một bản sao của struct-- nó không tạo ra một tham chiếu đến cấu trúc. Một chu trình tham chiếu mạnh mẽ sẽ chỉ liên quan đến các lớp và đóng cửa chứ không phải cấu trúc. –

+2

Loại 'Biến 'có phải là một lớp hay cấu trúc không? –

Trả lời

4

Darren đặt trong nhận xét: "DoesItLeak can't be a struct" Chúng tôi không thể có cấu trúc DoesItLeak là cấu trúc và giải quyết vấn đề chu kỳ tham chiếu mạnh mẽ một cách an toàn.

Các loại giá trị như cấu trúc tồn tại trên khung ngăn xếp. Đóng cửa và lớp học là các loại tham chiếu.

Khi Strong Reference Cycles for Closures section đặt nó:

This strong reference cycle occurs because closures, like classes, are reference types.

Kể từ khi struct có Variablelớp và việc đóng cửa đề cập đến self được lưu trữ vào lớp Variable sử dụng subscribeNext, nó tạo ra chu kỳ tài liệu tham khảo mạnh mẽ. Xem "Giải quyết chu kỳ tham chiếu mạnh mẽ để đóng cửa" trong Automatic Reference Counting Tài liệu của Apple.