开发者

Memory management with blocks - leak

开发者 https://www.devze.com 2023-03-31 03:55 出处:网络
I use blocks to perform an access check in a service class, but it is leaking memory. Can someone point out what the problem with my method is? The problem is probably related to which variables I am

I use blocks to perform an access check in a service class, but it is leaking memory. Can someone point out what the problem with my method is? The problem is probably related to which variables I am using within the blocks. I am accessing instance variables, method variables and referencing super.

-(RequestDO*)requestWithURL:(NSString*)url andDelegate:(id<RequestDelegate>)delegate_ signURL:(BOOL)sign_ request:(RequestDO*)request_ postData:(NSString*) postData_ {

    if([self requiresUpdatedAccess]){

        if(accessRequest == nil){
      开发者_JS百科      accessRequest = [[UpdatedAccessManager getPaymentStatus:self] retain];

            if(accessRequest.processStatus == kRequestComplete){ // Access check is complete (cached)
                [accessRequest release], accessRequest = nil;
                return [super requestWithURL:url andDelegate: delegate_ signURL:sign_ request:request_ postData: postData_];  // Do original service request
            }
            else{
                Block_release(completionBlock_);

                // When access check is done, we will perform this block to process the original request
                completionBlock_ = Block_copy(^(){
                    /*
                        url - an instance variable
                        delegate_, sign_, request_ and postData_ is method scoped variables
                    */                
                    NSString *updatedUrl = [Service updateUrlWithUserData: url];
                    [super requestWithURL:updatedUrl andDelegate: delegate_ signURL:sign_ request:request_ postData: postData_];
                });

                Block_release(failureBlock_);

                // If access check fails, we will perform this block to inform about the error
                failureBlock_ = Block_copy(^(RequestDO* req_, NSError* err_){
                    [delegate_ requestFailed:self.request withError: err_];
                });
            }
        }
    }
    else{
        return [super requestWithURL:url andDelegate: delegate_ signURL:sign_ request:request_ postData: postData_]; // This service does not need access check  
    }

    return accessRequest;
}

In dealloc i have Block_release for both blocks.


The block will retain all used vars. In your case the retain count of your object will be 2 due to the use of it in the block. Thus dealloc is not called and you have a classic retain cycle. To work around this declare

__block id blockSelf = self;

before the block and use blockSelf instead of self in your block.

0

精彩评论

暂无评论...
验证码 换一张
取 消