Question

I have a method call in class A:

GDataXMLElement *infoElement = [self getElementFromFilePath:filePath];
NSString *testStringA = [infoElement attributeForName:@"someAttribute"].stringValue;

and the method implementation in class B:

-(GDataXMLElement*)getElementFromFilePath:(NSString*)filePath {
    NSData *xmlData = [NSData dataWithContentsOfFile:filePath];
    GDataXMLDocument *infoXMLDoc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:nil];
    NSArray *infoArray = [infoXMLDoc.rootElement elementsForName:@"test"];
    GDataXMLElement *returnElement = (GDataXMLElement*)infoArray[0];
    NSString *testStringB = [returnElement attributeForName:@"someAttribute"].stringValue;
    return returnElement;
}

The returnElement at the end of the method in class B is perfectly initialized, and testStringB string contains the correct value. But in Class A, the contents of InfoElement are gone, and testStringA is nil.

I suspect that ARC is releasing GDataXMLDocument too early, and was able to stop this behaviour by tying the document to a property in class B:

@property (nonatomic,strong) GDataXMLDocument *infoXMLDoc;

But I am a little unsatisfied with this solution. I'll never use that property again, I just need the element to parse it one time only. If it is possible to stop the release with a property, is there also a way to do this within the method? I tried the __strong qualifier like this:

GDataXMLDocument __strong *infoXMLDoc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];

but that didn't help. So my questions, assuming ARC is indeed responsible:

1. Is is possible to tell ARC within a method to not release an object?

2. What did I not understand about the behaviour here? I am using ARC for some time now, this is the first time that I am stuck.

Was it helpful?

Solution

The GDataXMLNode.h header says:

it is up to the code that created a document to retain it for as long as any references rely on nodes inside that document tree.

The node you return from getElementFromFilePath depends on the parent (the GDataXMLDocument), but that is going to be released by ARC. You must retain the GDataXMLDocument somewhere for as long as you reference nodes and elements inside it. These are the semantics of the GDataXML* classes and you must follow them.

OTHER TIPS

I can't compile so this's just an educated guessing, but I suspect the problem is that you return a pointer to an object that is allocated and released inside the method:

GDataXMLElement *returnElement = (GDataXMLElement*)infoArray[0];

As you see you don't alloc returnElement, so ARC have no way to understand that you need it. It simply release infoArray when you exit from the method. If you copy the value (something like [(GDataXMLElement*)infoArray[0] copy] ) it should works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top