Search code examples
iosasynchronousautomatic-ref-countingretain

how to retain self in ARC mode, such as SKProductsRequest, retain self in start method then release after response come back?


See the following code sample (ARC mode), how SKProductsRequest retain itself to wait response come back? I mean in ARC mode you can't write [self retain], how does SKProductsRequest retain self in start method, then release self after response? As you know delegate is always weak.

SKProductsRequest is just an example here, now I need to such a service class and have no idea on how to retain self when request send out then release myself when response come back, anyone who has idea please share and discuss together, thanks in advance.

SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
productRequest = productsRequest;
productsRequest.delegate = self;
[productsRequest start];

PS: Regarding objc_setAssociatedObject, external long live object needed to keep retain relationship.

objc_setAssociatedObject(externalLiveObj, &kRetainSelfKey, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

Solution

  • Give yourself an instance variable. Set it to self when you start the request:

    @implementation MyRequestDelegate {
        MyRequestDelegate *me;
    }
    
    - (void)startProductsRequest {
        SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
        productRequest = productsRequest;
        productsRequest.delegate = self;
        [productsRequest start];
        me = self;  // this retains self
    }
    

    Then in the delegate method, set it back to nil:

    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
        // process response here, and then...
        me = nil;
    }