Objective c 带块的内存管理-泄漏

Objective c 带块的内存管理-泄漏,objective-c,ios,Objective C,Ios,我使用块在服务类中执行访问检查,但它正在泄漏内存。有人能指出我的方法有什么问题吗?问题可能与我在块中使用的变量有关。我正在访问实例变量、方法变量和引用super -(RequestDO*)requestWithURL:(NSString*)url andDelegate:(id<RequestDelegate>)delegate_ signURL:(BOOL)sign_ request:(RequestDO*)request_ postData:(NSString*) postDat

我使用块在服务类中执行访问检查,但它正在泄漏内存。有人能指出我的方法有什么问题吗?问题可能与我在块中使用的变量有关。我正在访问实例变量、方法变量和引用super

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

    if([self requiresUpdatedAccess]){

        if(accessRequest == nil){
            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;
}
-(RequestDO*)requestWithURL:(NSString*)url和delegate:(id)delegate\usignurl:(BOOL)sign\urequest:(RequestDO*)request\upostdata:(NSString*)postData{
如果([自我要求更新访问]){
if(accessRequest==nil){
accessRequest=[[UpdatedAccessManager getPaymentStatus:self]retain];
如果(accessRequest.processStatus==kRequestComplete){//访问检查已完成(缓存)
[accessRequest release],accessRequest=nil;
return[super requestWithURL:url和delegate:delegate\uSignURL:sign\uRequest:request\uPostData:postData];//执行原始服务请求
}
否则{
块释放(完成块释放);
//访问检查完成后,我们将执行此块来处理原始请求
completionBlock=块拷贝(^(){
/*
url-实例变量
委托、签名、请求和postData是方法作用域变量
*/                
NSString*updateUrl=[Service updateUrlWithUserData:url];
[super requestWithURL:updatedUrl和delegate:delegate\uSignURL:sign\uRequest:request\uPostData:postData_uu];
});
块释放(故障块释放);
//如果访问检查失败,我们将执行此块以通知错误
failureBlock=块拷贝(^(RequestDO*req,NSError*err){
[委托请求失败:self.request错误:错误];
});
}
}
}
否则{
return[super requestWithURL:url和delegate:delegate\uSignURL:sign\uRequest:request\uPostData:postData];//此服务不需要访问检查
}
返回访问请求;
}

在dealloc中,两个块都有块释放。

块将保留所有使用的变量。在您的情况下,由于在块中使用对象,对象的保留计数将为2。因此,不调用dealloc,您有一个经典的retain循环。来解决这个问题

__block id blockSelf = self;

在块之前,使用blockSelf而不是块中的self。

块将保留所有使用的变量。在您的情况下,由于在块中使用对象,对象的保留计数将为2。因此,不调用dealloc,您有一个经典的retain循环。来解决这个问题

__block id blockSelf = self;

在块之前,使用blockSelf而不是块中的self。

是的,我怀疑是这样的,但编译器不允许我写:u block id blockSuper=super;有意思,我不知道。也许其他人有更好的解决方案,但您可以通过创建一个新方法并使用selfBlock从块中调用此方法来解决此问题。@Andi:super是一个保留关键字。此外,如果使用ARC而不是u block,您应该使用u unsafe u unrepaired是的,我怀疑是这样的,但是编译器不允许我写:_block id blockSuper=super;有意思,我不知道。也许其他人有更好的解决方案,但您可以通过创建一个新方法并使用selfBlock从块中调用此方法来解决此问题。@Andi:super是一个保留关键字。同样,对于ARC而不是u block,您应该使用u不安全u未恢复