• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: ARC Retain Cycles
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ARC Retain Cycles


  • Subject: Re: ARC Retain Cycles
  • From: Dave <email@hidden>
  • Date: Mon, 21 Apr 2014 15:12:19 +0100

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 <email@hidden> 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 (email@hidden)

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:

This email sent to email@hidden


  • Follow-Ups:
    • Re: ARC Retain Cycles
      • From: Keary Suska <email@hidden>
    • Re: ARC Retain Cycles
      • From: Andy Lee <email@hidden>
References: 
 >ARC Retain Cycles (From: Dave <email@hidden>)
 >Re: ARC Retain Cycles (From: Cody Garvin <email@hidden>)
 >Re: ARC Retain Cycles (From: Quincey Morris <email@hidden>)
 >Re: ARC Retain Cycles (From: Dave <email@hidden>)
 >Re: ARC Retain Cycles (From: Quincey Morris <email@hidden>)
 >Re: ARC Retain Cycles (From: Dave <email@hidden>)
 >Re: ARC Retain Cycles (From: Roland King <email@hidden>)
 >Re: ARC Retain Cycles (From: Dave <email@hidden>)
 >Re: ARC Retain Cycles (From: Roland King <email@hidden>)

  • Prev by Date: Re: ARC Retain Cycles
  • Next by Date: Re: ARC Retain Cycles
  • Previous by thread: Re: ARC Retain Cycles
  • Next by thread: Re: ARC Retain Cycles
  • Index(es):
    • Date
    • Thread