Hi,

Amazing! I ***think*** I’ve found it! You were right, The profiler/leaks 
analyzer works really well, thanks for the tips!


myNetworkOperation.pResponseNetworkDelegate  or the corresponding class was the 
culprit! 

There is a delegate handler which makes passing and calling simple delegates a 
doddle. This was originally non ARC. 

There is a property defined:

@property (nonatomic,retain)            id                      payloadObject;

This is after I ARCed it, before that it didn’t specify it, e.g. it was 
(nonatomic). I must have made it retain when I was going through the 
properties. I’m not sure what the default is? I assume it must have been assign 
for this to work originally. I did a google for this and found conflicting 
results, according to the Objective-C Reference Manial, it’s assign. But I’m 
not sure where the “Offical” Objective-C manual is located to get it from the 
source.

payloadObject is just used to hold a copy of the object to pass to the delegate 
method


After changing this, the leaks when down by a massive factor. Basically it was 
hanging onto *every* response from the server!

I’m about to look through the code and see if I’ve made a similar mistake 
elsewhere. 

There are still a few more small leaks which I’m looking at now, but this is 
the mainstay - thanks again!


> myDataTask has a block which retains self, and self retains myDataTask 
> leading to a cycle, 


I’m a bit confused as it what you mean. Self here is a singleton, or at least 
there could be N of them (but actually there is only one in this case), but 
they stay around for the duration of the Application and never get released. In 
theory they could do I suppose, but there’s no need for them to be at the 
moment.

NSURLSessionDataTask*                                   myDataTask;

Is declared locally, I thought that it would get released when the 
“executeSyncRequestWithParameters:” method returns, which is after the code 
block does:
        
dispatch_group_leave(myDispatchGroup);

(oops! I’ve just relazied I left out an import chunk of code. The method is a 
lot bigger that the code I posted because it handling a lot of other cases that 
are not used for this problem. I’ve posted the code again.

This method is always called on a background thread, it issues a request, then 
blocks until the response comes back. This seems to work ok and I didn’t see 
this as a cycle in Leaks.

More later once I have had a chance to do some more digging.

Once thing I’m not sure about is if 

dispatch_group_t                                                        
myDispatchGroup;

Should be a local or property or if it matters. Originally it was a property, 
but I changed it. I wondering if I should have left it alone?

All the Best
Dave



-(JMNetworkCommandResponse*) 
executeSyncRequestWithParameters:(JMNetworkRequestParams*) theRequestParameters
{
JMNetworkCommandResponse*                               myNetworkResponse;
long                                                                            
myTimeOutStatus;
dispatch_group_t                                                        
myDispatchGroup;
NSURL*                                                                  myURL;
NSMutableURLRequest*                                            myURLRequest;
NSURLSessionDataTask*                                   myDataTask;
NSString*                                                                       
myParameterString;
NSData*                                                                 
myBodyData;
JMNetworkRequestHTTPDataMethod                  myTransferMethod;
JMNetworkOperationiOS7*                                 myNetworkOperation;

myURL = [[NSURL alloc] initWithString:theRequestParameters.pRequestURLString];
if (myURL == nil)
        return nil;

myNetworkOperation = [self 
newOperationWithRequestParameters:theRequestParameters];

myDispatchGroup = dispatch_group_create();
dispatch_group_enter(myDispatchGroup);

myDataTask = [self.pNetworkCommandURLSession dataTaskWithURL:myURL 
completionHandler:^(NSData* theResponseData,NSURLResponse* 
theURLResponse,NSError* theErrorInfo)
        {
        JMNetworkCommandResponse*                       myNewNetworkResponse;
        NSHTTPURLResponse*                                      
myHTTPURLResponse;
        NSInteger                                                       
myHTTPStatus;

        myHTTPURLResponse = (NSHTTPURLResponse*) theURLResponse;
        myHTTPStatus = myHTTPURLResponse.statusCode;
                        
        myNewNetworkResponse = [self 
newNetworkResponseWithRequestParameters:theRequestParameters 
andURLResponse:theURLResponse andResponseData:theResponseData 
andErrorInfo:theErrorInfo];
        [self setNetworkResponse:myNewNetworkResponse 
withRequestID:theRequestParameters.pRequestID];

        [myNetworkOperation.pResponseNetworkDelegate 
performDelegateSelectorOnMainThreadWithObject:myNewNetworkResponse];
        
        dispatch_group_leave(myDispatchGroup);
        }
        ];
        
[myDataTask resume];

//      dispatch_release(myDispatchGroup);

//************************************************************************************************************************************************
myTimeOutStatus = 
dispatch_group_wait(myDispatchGroup,dispatch_time(DISPATCH_TIME_NOW,kLTWNetworkOperationTimeOutPeriodNS));
if (myTimeOutStatus != 0)
        {
        myNetworkResponse = [self 
newErrorNetworkResponseWithErrorCode:kLTWNetworkManagerSyncTimeoutError 
andErrorMessage:NSLocalizedString(@"kLTWNetworkManagerSyncTimeoutError",@"executeSyncRequestWithParameters
 - Sync Request Timed Out")];

        [self setNetworkResponse:myNetworkResponse 
withRequestID:theRequestParameters.pRequestID];
        
        dispatch_group_leave(myDispatchGroup);
        }

//************************************************************************************************************************************************


//**
//**    Extract the Response from the Dictionary and Reset the Request
//**
myNetworkResponse = [self 
getNetworkResponseWithRequestID:theRequestParameters.pRequestID];
[self removeNetworkResponseWithRequestID:theRequestParameters.pRequestID];
        
return myNetworkResponse;
}

On 21 Apr 2014, at 13:39, Roland King <r...@rols.org> wrote:

> myDataTask has a block which retains self, and self retains myDataTask 
> leading to a cycle, would be my first thought. If nothing else also holds 
> onto that, you'd expect leaks to find it and give you a nice diagram showing 
> how it all hangs together, I believe leaks tracks dispatch_* (although I've 
> never tried it, they are full ARC'y objects now). 
> 


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to