0

I'm getting used to structs over classes in Swift, but have a concern about best practices if I'm possibly generating retain cycles due to closures not having [unowned self] or [weak self] ? (which isn't allowed in a struct or protocol). And the fact that I'm making all static funcs.

struct OrgAPIservice {

    static func getOrganizations(sinceSyncToken: ...
                                 completion:@escaping (_ orgsList: [Organization]?, _ error: AppError?) -> Void) {

        apiProvider.request(.getOrganizations(...)) { result in
            switch result {
            case .success(let response):

            case .failure(let error):
                completion (nil, getAppErrorFromMoya(with: error))
            }
        }
    }

}
Sebastian Dwornik
  • 2,526
  • 2
  • 34
  • 57
  • You are not retaining any closures so there is no retain cycle. Nothing here to worry about. — But what is the point of the `static`? – matt Aug 10 '18 at 15:59
  • The `static` is convenient versus always creating an object just to process some data. eg. I find `OrgAPIservice.getOrganizations(..)` simpler then `OrgAPIservice().getOrganizations(..)` – Sebastian Dwornik Aug 10 '18 at 16:05
  • 2
    A static func has no `self` (because there is no instance), so communication between of values between methods becomes impossible. Instances have independent instance properties which is safe and clear. The usual thing is to have a single instance of your "helper" struct as a property of your view controller class. You asked about best practice and I'm replying. – matt Aug 10 '18 at 16:30
  • @matt - "so communication between of values between methods becomes impossible"? Surely static functions can use static properties in a similar way instance functions can use instance properties. It is one thing to argue it is not "best practice", but "impossible"? – CRD Aug 11 '18 at 05:07

1 Answers1

0

You can have weak self in your closure if the caller of the function is an object. The self refers to the object that provide the closure. It does not refer to the variable that owns the closure.

For example, if you have a class MyClass, then you can do

class MyClass {

    func callApi() {
        OrgAPIservice.getOrganizations {
            [weak self] in
            // ....
        }
    }
}
ukim
  • 2,395
  • 15
  • 22
  • Correct. But internally `apiProvider.request(.getOrganizations(...)) { result in` embeds a closure. Do `structs` treat closures differently then `classes`? – Sebastian Dwornik Aug 10 '18 at 16:07
  • There is no difference. An escaping closure is just a variable which can capture references from the outside scopes, which means it has references to variables that are not defined in it. Only when the owner struct has a strong reference to an escaping closure, and the closure has a strong reference path to the struct will there be a retain cycle. @SebastianDwornik – ukim Aug 10 '18 at 16:15