views:

1198

answers:

3

Would it shed more light if I told that fetchHTML was being called in a seperate thread? I am also seeing several messages in the debug console such as:

_NSAutoreleaseNoPool(): Object 0xd92860 of class NSCFDictionary autoreleased with no pool in place - just leaking

_NSAutoreleaseNoPool(): Object 0xd92800 of class NSCFString autoreleased with no pool in place - just leaking

I am new to iPhone app development, Objective-C but not new to programming or C/C++. I am using the leaks performance tool and it shows many leaks. This is a 10.5 kb leak and it occurs on the line:

NSString * xml = [NSString stringWithContentsOfURL:urlobj];

The stack trace on this below is:

stringWithContentsOfURL
initWithContentsOfURL
initWithDataOfEncoding
...

Does anyone have an idea why this must be happening. I am under the impression that I get an autorelease object here and I can return this to the caller without calling retain. I am not using the xml object to store in an instance variable, just for processing.

Here is the function code:

- (NSString *) fetchHTML: (NSString* ) url{
    @try
    {
        NSURL* urlobj = [NSURL URLWithString:url];
        NSString * xml = [NSString stringWithContentsOfURL:urlobj];
        return xml;
    }
    @catch( NSException *ex){
        NSLog(@"Error fetchingHTML");
        return nil;
    }
    return nil;
}
+1  A: 

Yup; that shouldn't be leaking.

It might be a false positive in that the URL subsystem is caching the contents of the URL and doing so in a way where the pointer is no longer visible to leaks analysis.

If you can, retry the test on Snow Leopard. Leaks detection on Snow Leopard is significantly faster and more accurate.

bbum
+1  A: 

I completely agree with you that this should not cause a leak. I've been coding in Cocoa/Objective-C for 2 years now, and that looks like it should work.

That being said, I notice that Apple's documentation indicates that the stringWithContentsOfURL: method is being deprecated. Perhaps it would work as follows:

NSString * xml = [[NSString alloc]
                  initWithContentsOfURL:urlobj
                               encoding:NSASCIIStringEncoding
                                  error:nil];
return [xml autorelease];
e.James
I can definitely try that. Would it through some light, is I told you that the fetchHTML is being called in a separate thread. Do I need to create a new autoreleasepool?In my debug console I see several messages like "Object **** of class *** autoreleased with no pool in place - just leaking
I'm afraid I'm no expert on the threaded use of autorelease pools. That does sound like it could be the problem, though. Why not add that information to the question?
e.James
+1  A: 

As the error message says, there's no autorelease pool for the string to go into, and that creates a leak. NSAutoreleasePools exist on a per-thread basis. Cocoa creates one in the main event loop of the main thread, but that's the only one it creates for you. If you're somewhere other than the main thread and you're going to be dealing with autoreleased objects, you need to create an autorelease pool for that thread as well.

You can check out the NSAutoreleasePool docs for more information on how autorelease pool stacks work.

Chuck
Thanks, I added an autoreleasepool wrapper around my thread function but i get a objc_msgSend error.Here is the code:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];[dataArray replaceObjectAtIndex:2 withObject: "now what"];[pool release];Any idea what is going on here?
Try [dataArray replaceObjectAtIndex:2 withObject:@"now what"]; Note the @ symbol.
Mike McMaster
Indeed, that replaceObjectAtIndex... line can't possibly have worked before the autorelease pool was there either.
Chuck