Re: Leaked NSString from class_getInstanceMethod
Christiaan Hofman <[email protected]> Sat, 23 Jul 2011 19:14:36 +0200
| Newsgroups | gmane.comp.macosx.devel |
|---|---|
| Message-ID | <[email protected]> |
On Jul 23, 2011, at 17:36, Kyle Sluder wrote: > On Sat, Jul 23, 2011 at 5:29 AM, Christiaan Hofman = <[email protected]> wrote: >> When I use the function class_getInstanceMethod() in +load in a = PDFDocument category, I get the following message in the console log: >>=20 >> *** __NSAutoreleaseNoPool(): Object 0x100404b30 of class NSCFString = autoreleased with no pool in place - just leaking >>=20 >> 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). >>=20 >> 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? >=20 > 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. >=20 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 > this is a known shortcoming of +load: > = http://www.friday.com/bbum/2009/09/06/iniailize-can-be-executed-multiple-t= imes-load-not-so-much/ >=20 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? >=20 > --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