Discussion:
Leaked NSString from class_getInstanceMethod
Christiaan Hofman
2011-07-23 12:29:55 UTC
Permalink
When I use the function class_getInstanceMethod() in +load in a PDFDocument category, I get the following message in the console log:

*** __NSAutoreleaseNoPool(): Object 0x100404b30 of class NSCFString autoreleased with no pool in place - just leaking

I really don't do anything else than what I said (at least in a test, the actual code I would like to have of course does a bit more, but that's not relevant).

this makes absolutely no sense to me. The function is a runtime method, so it should never even use any Cocoa itself. So what NSCFString could this actually be? It also does not happen when I do the same in categories on other classes, including PDFKit classes. Anyone has an idea?

thanks,
Christiaan
Christiaan Hofman
2011-07-23 17:14:36 UTC
Permalink
Post by Christiaan Hofman
*** __NSAutoreleaseNoPool(): Object 0x100404b30 of class NSCFString autoreleased with no pool in place - just leaking
I really don't do anything else than what I said (at least in a test, the actual code I would like to have of course does a bit more, but that's not relevant).
this makes absolutely no sense to me. The function is a runtime method, so it should never even use any Cocoa itself. So what NSCFString could this actually be? It also does not happen when I do the same in categories on other classes, including PDFKit classes. Anyone has an idea?
Not entirely sure why a runtime method can't use an NSAutoreleasePool.
It sounds like it would be nice if it didn't, but I don't think
there's any such guarantee.
I don't think the runtime (function, not method) should ever use any Cocoa methods and objects, because the runtime is called before the Cocoa classes are properly setup and initialize. Calling any Cocoa from a runtime method will almost certainly lead to problems, because the whole setup of Cocoa itself will be mixed up. So I disagree that there's no such guarantee. Quite to the contrary, if such a guarantee would not exist, than logically the whole runtime would be internally inconsistent and buggy by design. I cannot believe that would be the case.
The last comment on this blog post from Bill Bumgarner implies that
http://www.friday.com/bbum/2009/09/06/iniailize-can-be-executed-multiple-times-load-not-so-much/
I think you don't understand the problem. It's not the fact that there's no autorelease pool present, I know that. The problem is that an autorelease pool would be needed in the first place. I am not using Cocoa, and therefore I never should need an autorelease pool.
That leads us to the question: why are you using +load in the first
place? As bbum says, it's a very fragile time. This method is
executing during static constructor time, before the C runtime has
even called your main(). Can you defer your work to +initialize?
--Kyle Sluder
+initialize is defined for a class, while +load is defined both for a class and/or a category. More precisely, for each class only one version of +initialize is called (once or more than once), while *all* variants of +load defined in *all* categories are called by the runtime. As I am talking about a category, +initialize does not apply, as it cannot be (safely) defined (and called) in a category.

And I am using functions rather than Cocoa precisely because I know it's fragile. I do know very well that you simply cannot use Cocoa in +load, that's always dangerous, because +load can be called before Cocoa has been fully set up and initialized. So also using my own autorelease pool in +load is dangerous, so I cannot even do what this comment suggests.

What is also strange is that when I define a local autorelease pool, its -addObject: method is never called.

Something very strange and buggy is going on. I tend to think now that it's really the log that's wrong rather than what it says.

Christiaan
Kyle Sluder
2011-07-23 17:19:04 UTC
Permalink
Post by Christiaan Hofman
I don't think the runtime (function, not method) should ever use any Cocoa methods and objects, because the runtime is called before the Cocoa classes are properly setup and initialize. Calling any Cocoa from a runtime method will almost certainly lead to problems, because the whole setup of Cocoa itself will be mixed up. So I disagree that there's no such guarantee. Quite to the contrary, if such a guarantee would not exist, than logically the whole runtime would be internally inconsistent and buggy by design. I cannot believe that would be the case.
[ snip ]
Post by Christiaan Hofman
And I am using functions rather than Cocoa precisely because I know it's fragile. I do know very well that you simply cannot use Cocoa in +load, that's always dangerous, because +load can be called before Cocoa has been fully set up and initialized. So also using my own autorelease pool in +load is dangerous, so I cannot even do what this comment suggests.
What is also strange is that when I define a local autorelease pool, its -addObject: method is never called.
There's no guarantee that the runtime goes through the
NSAutoreleasePool facade to get at the underlying autorelease service.

--Kyle Sluder

Loading...