Zombie object being messaged - why?
Dear list, In a document based app running under ARC, I've been struggling for an eternity to get to the bottom of an occasional crash which happens when closing a document. I've spent a huge amount of time working on my -tearDown procedure which I call in my NSDocument subclass' -windowWillClose: and which subsequently calls -tearDown on many other app components. I also hit the same crash: [MHControlsTabBarController performSelector:withObject:]: message sent to deallocated instance 0x1075d2cb0 MHControlsTabBarController is a view controller whose view is added to the document's main window when the document loads. In my document's -tearDown I do: // clean up tab bar controls [self.controlsTabBarController tearDown]; self.controlsTabBarController = nil; In [MHControlsTabBarController tearDown] I nil out various state variables. I've also tried various things in that -tearDown, like removing the view controller's view from the superview, cancelling any run loop performs by doing: [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self]; [[NSRunLoop mainRunLoop] cancelPerformSelectorsWithTarget:self]; nilling out all IBOutlets, etc, but nothing helps so far. I ran the app under instruments and I get a nice zombie message when closing the document. The object history is long, but the last few entries are: # Address CategoryEvent Type RefCt Timestamp Size Responsible Library Responsible Caller 21110x10a395410 MHControlsTabBarController Retain 2 03:29.823.791 0 TeXnicle-[TeXProjectDocument controlsTabBarController] 21120x10a395410 MHControlsTabBarController Autorelease 03:29.823.792 0 TeXnicle-[TeXProjectDocument controlsTabBarController] 21130x10a395410 MHControlsTabBarController Retain 3 03:29.823.792 0 TeXnicle-[TeXProjectDocument tearDown] 21140x10a395410 MHControlsTabBarController Release 2 03:29.825.781 0 TeXnicle-[TeXProjectDocument tearDown] 21150x10a395410 MHControlsTabBarController Release 1 03:29.825.784 0 TeXnicle-[TeXProjectDocument setControlsTabBarController:] 21160x10a395410 MHControlsTabBarController Release 0 03:29.877.132 0 Foundation -[NSAutoreleasePool drain] 21170x10a395410 MHControlsTabBarController Zombie -1 03:31.405.789 0 AppKit -[NSWindow sendEvent:] Should I interpret this as a window trying to message the object? Am I somehow over-reasling? Under ARC, I can't, right? If it's not coming from a window, how can I figure out which object is trying to message this deallocated MHControlsTabBarController? There are a number of timer-based activities which check the state of this controls controller but in the document's -tearDown I try to stop all timers. The problem is, how can I ensure that all timers (and any actions already triggered) have stopped, before I go ahead tearing down everything else? I sort of need to delay the document closing somehow, but I asked about this in an earlier thread (this has been a lng story) and was advised (probably rightly) that this was bad design. But this seems like a general problem to me, for which there is surely a general pattern which solves it. If I have timer-based activities, how do I make sure they are stopped before the rug is pulled from under their feet? Many thanks for your patience with both of today's long posts. Martin ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
On Jan 25, 2013, at 8:52 AM, Martin Hewitson wrote: > In a document based app running under ARC, I've been struggling for an > eternity to get to the bottom of an occasional crash which happens when > closing a document. I've spent a huge amount of time working on my -tearDown > procedure which I call in my NSDocument subclass' -windowWillClose: and which > subsequently calls -tearDown on many other app components. I also hit the > same crash: > > [MHControlsTabBarController performSelector:withObject:]: message sent to > deallocated instance 0x1075d2cb0 First things first--you are getting a crash, which means that the debugger should put you exactly in the place where you can inspect the arguments being sent via this method which will likely tell you what object is sending it and potentially why. Without this knowledge, everything you do is just random stabs and may not solve the problem even if it seems to go away. Just a quick suggestion--have you searched your code to see if you ever call this method? > MHControlsTabBarController is a view controller whose view is added to the > document's main window when the document loads. > > In my document's -tearDown I do: > > // clean up tab bar controls > [self.controlsTabBarController tearDown]; > self.controlsTabBarController = nil; > > In [MHControlsTabBarController tearDown] I nil out various state variables. > I've also tried various things in that -tearDown, like removing the view > controller's view from the superview, cancelling any run loop performs by > doing: > > [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self]; > [[NSRunLoop mainRunLoop] cancelPerformSelectorsWithTarget:self]; IIRC performSelector:withObject: is not a run loop action--it is immediate dispatch, so doing the above is one of those useless stabs I mentioned. > nilling out all IBOutlets, etc, but nothing helps so far. > Should I interpret this as a window trying to message the object? Am I > somehow over-reasling? Under ARC, I can't, right? If it's not coming from a > window, how can I figure out which object is trying to message this > deallocated MHControlsTabBarController? If you are using ARC, I don't think you should be doing any explicit memory management except to explicitly balance other explicit memory management calls; and if you aren't, then you aren't over-releasing. Minimally, some object has a weak reference to your MHControlsTabBarController, and that can happen, so once you know who and why you can prevent it. > There are a number of timer-based activities which check the state of this > controls controller but in the document's -tearDown I try to stop all timers. > The problem is, how can I ensure that all timers (and any actions already > triggered) have stopped, before I go ahead tearing down everything else? I > sort of need to delay the document closing somehow, but I asked about this in > an earlier thread (this has been a lng story) and was advised (probably > rightly) that this was bad design. But this seems like a general problem to > me, for which there is surely a general pattern which solves it. If I have > timer-based activities, how do I make sure they are stopped before the rug is > pulled from under their feet? Whichever object set up the timers should invalidate them before their target would be released, so the validity of the target should be known and deterministic to that object. Sometimes easier said than done, but there it is. In any case it is not likely that a timer is responsible since they are supposed to retain or maintain a strong reference to their target until they are invalidated, after which time they would not fire anyway. HTH, Keary Suska Esoteritech, Inc. "Demystifying technology for your home or business" ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
On Jan 25, 2013, at 10:52 AM, Martin Hewitson wrote: > Should I interpret this as a window trying to message the object? Am I > somehow over-reasling? Under ARC, I can't, right? Assuming there isn't a bug in ARC, you could still be over-releasing if: * You're supporting 10.6 and so you're using __unsafe_unretained because you can't use __weak. * You've incorrectly used the __bridge keywords somewhere, like maybe you used __bridge or __bridge_transfer when you should have used __bridge_retained. --Andy ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
On Jan 25, 2013, at 7:52 AM, Martin Hewitson wrote: > 2117 0x10a395410 MHControlsTabBarController Zombie -1 > 03:31.405.789 0 AppKit -[NSWindow sendEvent:] > > Should I interpret this as a window trying to message the object? Am I > somehow over-reasling? Under ARC, I can't, right? If it's not coming from a > window, how can I figure out which object is trying to message this > deallocated MHControlsTabBarController? First, you should get the full stack trace for the zombie message. That might help identify who's doing what. One common failure that ARC does not fix is traditional delegates in AppKit and other system frameworks. For various reasons those delegates are __unsafe_unretained instead of ARC __weak. That means if you forget to clean up some delegate somewhere then AppKit's will be left with a dangling pointer. Then AppKit tries to use the delegate later and crashes. Controller objects are often used as delegates so I bet something like this is going on. If so, the stack trace of the zombie message will probably show AppKit calling -respondsToSelector: or one of the delegate methods on your zombified controller object. -- Greg Parker gpar...@apple.com Runtime Wrangler ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
On Jan 25, 2013, at 10:33 , Quincey Morris wrote: > Since the retain count goes from 1 to 0 here Aargh, did it again! The count is actually going from 2 to 1 in your history. I meant of course, discounting the balanced retain/release pairs, it's the last remaining retain count being decremented. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
Hi Keary, I appreciate your response. I'll try to answer below. >> >> In a document based app running under ARC, I've been struggling for an >> eternity to get to the bottom of an occasional crash which happens when >> closing a document. I've spent a huge amount of time working on my -tearDown >> procedure which I call in my NSDocument subclass' -windowWillClose: and >> which subsequently calls -tearDown on many other app components. I also hit >> the same crash: >> >> [MHControlsTabBarController performSelector:withObject:]: message sent to >> deallocated instance 0x1075d2cb0 > > First things first--you are getting a crash, which means that the debugger > should put you exactly in the place where you can inspect the arguments being > sent via this method which will likely tell you what object is sending it and > potentially why. Unfortunately, either that isn't happening, or I'm not understanding what I see. Here's an example backtrace: [MHControlsTabBarController performSelector:withObject:]: message sent to deallocated instance 0x104bc33f0 (lldb) bt * thread #1: tid = 0x1d07, 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) frame #0: 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158 frame #1: 0x7fff8ff5f3b8 CoreFoundation`_CF_forwarding_prep_0 + 232 frame #2: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #3: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #4: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #5: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #6: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #7: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #8: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #9: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #10: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #11: 0x7fff93648a83 AppKit`-[NSWindow sendEvent:] + 7994 frame #12: 0x7fff9364442c AppKit`-[NSApplication sendEvent:] + 4969 frame #13: 0x7fff9355a2fa AppKit`-[NSApplication run] + 636 frame #14: 0x7fff934fecb6 AppKit`NSApplicationMain + 869 frame #15: 0x00011d02 TeXnicle`main + 34 at main.m:32 frame #16: 0x00011cd4 TeXnicle`start + 52 Here's another example: [MHControlsTabBarController performSelector:withObject:]: message sent to deallocated instance 0x127ef9fd0 (lldb) bt * thread #1: tid = 0x1d07, 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) frame #0: 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158 frame #1: 0x7fff8ff5f3b8 CoreFoundation`_CF_forwarding_prep_0 + 232 frame #2: 0x7fff93680ef7 AppKit`forwardMethod + 125 frame #3: 0x7fff93648a83 AppKit`-[NSWindow sendEvent:] + 7994 frame #4: 0x7fff9364442c AppKit`-[NSApplication sendEvent:] + 4969 frame #5: 0x7fff9355a2fa AppKit`-[NSApplication run] + 636 frame #6: 0x7fff934fecb6 AppKit`NSApplicationMain + 869 frame #7: 0x00012022 TeXnicle`main + 34 at main.m:32 frame #8: 0x00011ff4 TeXnicle`start + 52 > Without this knowledge, everything you do is just random stabs and may not > solve the problem even if it seems to go away. That's exactly how I feel. I just keep trying things, but nothing seems very systematic. Most unsatisfying. > > Just a quick suggestion--have you searched your code to see if you ever call > this method? No, I never message MHControlsTabBarController with performSelector:... > >> MHControlsTabBarController is a view controller whose view is added to the >> document's main window when the document loads. >> >> In my document's -tearDown I do: >> >> // clean up tab bar controls >> [self.controlsTabBarController tearDown]; >> self.controlsTabBarController = nil; >> >> In [MHControlsTabBarController tearDown] I nil out various state variables. >> I've also tried various things in that -tearDown, like removing the view >> controller's view from the superview, cancelling any run loop performs by >> doing: >> >> [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self]; >> [[NSRunLoop mainRunLoop] cancelPerformSelectorsWithTarget:self]; > > IIRC performSelector:withObject: is not a run loop action--it is immediate > dispatch, so doing the above is one of those useless stabs I mentioned. Ah, good to know. So I don't need to do that. > >> nilling out all IBOutlets, etc, but nothing helps so far. > >> Should I interpret this as a window trying to message the object? Am I >> somehow over-reasling? Under ARC, I can't, right? If it's not coming from a >> window, how can I figure out which object is trying to message this >> deallocated MHControlsTabBarController? > > If you are using ARC, I don't think you should be doing any explicit memory > management except to explicitly balance other explicit m
Re: Zombie object being messaged - why?
(resent) On Jan 25, 2013, at 07:52 , Martin Hewitson wrote: > 2111 0x10a395410 MHControlsTabBarController Retain 2 > 03:29.823.791 0 TeXnicle-[TeXProjectDocument > controlsTabBarController] > 2112 0x10a395410 MHControlsTabBarController Autorelease > 03:29.823.792 0 TeXnicle-[TeXProjectDocument > controlsTabBarController] > 2113 0x10a395410 MHControlsTabBarController Retain 3 > 03:29.823.792 0 TeXnicle-[TeXProjectDocument tearDown] > 2114 0x10a395410 MHControlsTabBarController Release 2 > 03:29.825.781 0 TeXnicle-[TeXProjectDocument tearDown] > 2115 0x10a395410 MHControlsTabBarController Release 1 > 03:29.825.784 0 TeXnicle-[TeXProjectDocument > setControlsTabBarController:] > 2116 0x10a395410 MHControlsTabBarController Release 0 > 03:29.877.132 0 Foundation -[NSAutoreleasePool drain] > 2117 0x10a395410 MHControlsTabBarController Zombie -1 > 03:31.405.789 0 AppKit -[NSWindow sendEvent:] > > Should I interpret this as a window trying to message the object? Am I > somehow over-reasling? Under ARC, I can't, right? If it's not coming from a > window, how can I figure out which object is trying to message this > deallocated MHControlsTabBarController? I think there's a bit more information here than you think. Yes, the view controller is being messaged because your window is processing an event. I'll come back to this in a minute. First, we can winnow the history in two stages: -- Ignore the retain and release from 'tearDown', since those are balanced. -- Ignore the retain/autorelease from 'controlsTabBarController' and the balancing release in 'drain'. That leaves this: > 2115 0x10a395410 MHControlsTabBarController Release 1 > 03:29.825.784 0 TeXnicle-[TeXProjectDocument > setControlsTabBarController:] and there's every indication this is the 'self.controlsTabBarController = nil' you showed earlier in your message. Since the retain count goes from 1 to 0 here, there shouldn't be any remaining references to the view controller. But there is one, as your crash proves. There are two possibilities: 1. You have a simple memory management bug where you overreleased the view controller, likely when you initially put its value in the '_controlsTabBarController' ivar (or whatever it's called) that backs the "controlsTabBarController" property. 2. The remaining reference is unretained. If it's #1, it shouldn't be too hard to find. At worst, you might have to go through the whole Instruments history matching things. If it's #2, it can be harder to find, but the 'sendEvent:' message is an excellent clue. Why would a window, dispatching an incoming event, send a message to a view controller? Well, normally it won't. It's going to transform the event into a NSResponder message and send it to something in the responder chain, and normally view controllers *aren't* in the responder chain. But it does send it to the view controller! My conclusion is that you put the view controller in the responder chain yourself, and you forgot to take it out. This accords with #2, because it's unlikely you *retained* the view controller before adding it to the responder chain. Note that I say "you", but it might of course have been done by a 3rd party library or some code you don't have direct knowledge of. Anyway I would suggest you investigate both #1 (by further examining your code for memory management errors, and winnowing the full Instruments history of the object) and #2 (to understand which presumably-unretained reference is being used for the zombie messaging). ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
On Jan 25, 2013, at 11:51 AM, Martin Hewitson wrote: >> First things first--you are getting a crash, which means that the debugger >> should put you exactly in the place where you can inspect the arguments >> being sent via this method which will likely tell you what object is sending >> it and potentially why. > > Unfortunately, either that isn't happening, or I'm not understanding what I > see. Here's an example backtrace: You may not be able to access the arguments when you have zombies enabled. Turn it off, and when the debugger breaks, po the arguments. The selector is most useful to know, but also knowing the object argument will clue to why your instance is getting the message. The backtrace seems to show that your instance is still in the responder chain, and knowing the above arguments will tell you whether its delegation or something else. > [MHControlsTabBarController performSelector:withObject:]: message sent to > deallocated instance 0x104bc33f0 > (lldb) bt > * thread #1: tid = 0x1d07, 0x7fff8ff5f4ce CoreFoundation`___forwarding___ > + 158, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) >frame #0: 0x7fff8ff5f4ce CoreFoundation`___forwarding___ + 158 >frame #1: 0x7fff8ff5f3b8 CoreFoundation`_CF_forwarding_prep_0 + 232 >frame #2: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #3: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #4: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #5: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #6: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #7: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #8: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #9: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #10: 0x7fff93680ef7 AppKit`forwardMethod + 125 >frame #11: 0x7fff93648a83 AppKit`-[NSWindow sendEvent:] + 7994 >frame #12: 0x7fff9364442c AppKit`-[NSApplication sendEvent:] + 4969 >frame #13: 0x7fff9355a2fa AppKit`-[NSApplication run] + 636 >frame #14: 0x7fff934fecb6 AppKit`NSApplicationMain + 869 >frame #15: 0x00011d02 TeXnicle`main + 34 at main.m:32 >frame #16: 0x00011cd4 TeXnicle`start + 52 Keary Suska Esoteritech, Inc. "Demystifying technology for your home or business" ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Getting file type from Save dlog
I'm not understanding how, if the user changes the type of file being saved in the Save dlog, how that type gets back to the document being saved. I've added an accessory panel from which the user can choose the file type being saved. Each type changes the extension of the file name in the name field. But when it gets back to my writeToURL: method, the typeName param is always the primary file type and never what the user might have changed it to. I've tried inspecting fileTypeFromLastRunSavePanel: and fileType:, but they're always the same as typeName. How is the type chosen in the dlog (it's a valid extension and UTI) supposed to get passed back to the document? -- Steve Mills office: 952-818-3871 home: 952-401-6255 cell: 612-803-6157 ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Getting file type from Save dlog
If you’re using your own accessory view instead of the built-in one (shouldRunSavePanelWithAccessoryView), you’re responsible for changing the value of fileTypeFromLastRunSavePanel. One way to do this is to make your NSDocument instance the target of the popup button’s action and change an internal ivar inside that action method. -KP On Jan 25, 2013, at 2:29 PM, Steve Mills wrote: > I'm not understanding how, if the user changes the type of file being saved > in the Save dlog, how that type gets back to the document being saved. I've > added an accessory panel from which the user can choose the file type being > saved. Each type changes the extension of the file name in the name field. > But when it gets back to my writeToURL: method, the typeName param is always > the primary file type and never what the user might have changed it to. I've > tried inspecting fileTypeFromLastRunSavePanel: and fileType:, but they're > always the same as typeName. > > How is the type chosen in the dlog (it's a valid extension and UTI) supposed > to get passed back to the document? > > -- > Steve Mills > office: 952-818-3871 > home: 952-401-6255 > cell: 612-803-6157 > > > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > 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: > https://lists.apple.com/mailman/options/cocoa-dev/kperry%40apple.com > > This email sent to kpe...@apple.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Getting file type from Save dlog
I'm going from memory, but I don't think you need to do your own accessory view. Just call setFileTypes: with the desired types on the NSOpenPanel instance and you should get a popup by default, I think ... ? You can then get the fileType from that object back or so. Cheers, -- Uli Kusterer "The Witnesses of TeachText are everywhere..." http://www.masters-of-the-void.com On 25.01.2013, at 23:29, Steve Mills wrote: > I'm not understanding how, if the user changes the type of file being saved > in the Save dlog, how that type gets back to the document being saved. I've > added an accessory panel from which the user can choose the file type being > saved. Each type changes the extension of the file name in the name field. > But when it gets back to my writeToURL: method, the typeName param is always > the primary file type and never what the user might have changed it to. I've > tried inspecting fileTypeFromLastRunSavePanel: and fileType:, but they're > always the same as typeName. > > How is the type chosen in the dlog (it's a valid extension and UTI) supposed > to get passed back to the document? > > -- > Steve Mills > office: 952-818-3871 > home: 952-401-6255 > cell: 612-803-6157 > > > > ___ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > 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: > https://lists.apple.com/mailman/options/cocoa-dev/witness.of.teachtext%40gmx.net > > This email sent to witness.of.teacht...@gmx.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString boundingRectWithSize vs. paragraph margins
I just made a demo project to explore what the heck values NSStringDrawing is returning: https://github.com/kylesluder/NSStringDrawer The line fragment results seem sensible to me, and both the glyph origin and line fragment results make sense when using device metrics, but asking for the baseline-rendering-mode glyph origin with a nonzero head indent returns a rect that always lies at x=0. This runs contrary to the docs for -boundingRectWithSize:options:attributes:, which state "the rect origin returned from this method is the first glyph origin." If this were the case, constructing a text system and querying the layout manager for -locationForGlyphIndex:0 clearly shows us that we should expect a rect that is offset by the amount of the first-line head indent. I've filed rdar://problem/13091382 on this issue, but fixing it would produce a significant-enough change that I think Apple will be very hesitant to fix it. --Kyle Sluder On Thu, Jan 24, 2013, at 12:13 PM, Kyle Sluder wrote: > On Thu, Jan 24, 2013, at 11:52 AM, Kyle Sluder wrote: > > > I expect this method to tell me the size of a rectangle (e.g. a bitmap > > > context) such that if I draw my attributed string into that rectangle, it > > > will all fit. When I say "all" I mean "all", including the margins. > > > > Considering the method is named -boundingRect…, I wouldn't expect this. > > What you're looking for is the line fragment rect, and I can understand > > why you would think passing NSStringDrawingUsesLineFragmentOrigin as an > > option would yield this information. Instead, it seems to offer the > > bounding rect of the glyph range in line fragment coordinates, which I > > would surmise is more useful information in NSStringDrawing's primary > > intended use cases. > > Huh, I just tried this in python and I got results that more closely > match _your_ expectation, not _mine_: > > >>> ps = AppKit.NSMutableParagraphStyle.alloc().init() > >>> ps.setHeadIndent_(20) > >>> ps.setFirstLineHeadIndent_(30) > >>> attrs = {AppKit.NSParagraphStyleAttributeName : ps} > >>> attributedString = > >>> Foundation.NSAttributedString.alloc().initWithString_attributes_("A", > >>> attrs) > >>> attributedString.boundingRectWithSize_options_(Foundation.NSMakeSize(1000, > >>> 1000), AppKit.NSStringDrawingUsesLineFragmentOrigin) > size= height=15.0>> > > >>> attributedString.boundingRectWithSize_options_(Foundation.NSMakeSize(1000, > >>> 1000), 0) > size= height=15.0>> > > Note that when I pass NSStringDrawingUsesLineFragmentOrigin, I get a > width of 38 points, whereas if I omit it, I get a width of 8. > > But if I then add a tailIndent of 40, my metrics don't grow at all: > > >>> ps.setTailIndent_(40) > >>> attributedString.boundingRectWithSize_options_(Foundation.NSMakeSize(1000, > >>> 1000), AppKit.NSStringDrawingUsesLineFragmentOrigin) > size= height=15.0>> > > >>> attributedString.boundingRectWithSize_options_(Foundation.NSMakeSize(1000, > >>> 1000), 0) > size= height=15.0>> > > So my current theory is that the advancement of the glyph is taken into > account when computing the glyph's bounding box in line fragment origin > mode. But that makes me a little surprised that the x-coordinate of the > origin of the baseline-relative rect is 0 in all cases; I would expect > it to include the glyph advancement (30). > > --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
This was held for moderation for being too large (for some reason), so I've trimmed it and resent it. >> >> Should I interpret this as a window trying to message the object? Am I >> somehow over-reasling? Under ARC, I can't, right? If it's not coming from a >> window, how can I figure out which object is trying to message this >> deallocated MHControlsTabBarController? > > I think there's a bit more information here than you think. > > Yes, the view controller is being messaged because your window is processing > an event. I'll come back to this in a minute. > > First, we can winnow the history in two stages: > > -- Ignore the retain and release from 'tearDown', since those are balanced. > > -- Ignore the retain/autorelease from 'controlsTabBarController' and the > balancing release in 'drain'. > > That leaves this: > >> 2115 0x10a395410 MHControlsTabBarController Release 1 >> 03:29.825.784 0 TeXnicle-[TeXProjectDocument >> setControlsTabBarController:] > > and there's every indication this is the 'self.controlsTabBarController = > nil' you showed earlier in your message. Since the retain count goes from 1 > to 0 here, there shouldn't be any remaining references to the view > controller. But there is one, as your crash proves. There are two > possibilities: > > 1. You have a simple memory management bug where you overreleased the view > controller, likely when you initially put its value in the > '_controlsTabBarController' ivar (or whatever it's called) that backs the > "controlsTabBarController" property. I always use self.controlsTabBarController - I don't directly access the backing ivar anywhere. > > 2. The remaining reference is unretained. > > If it's #1, it shouldn't be too hard to find. At worst, you might have to go > through the whole Instruments history matching things. > > If it's #2, it can be harder to find, but the 'sendEvent:' message is an > excellent clue. Why would a window, dispatching an incoming event, send a > message to a view controller? Well, normally it won't. It's going to > transform the event into a NSResponder message and send it to something in > the responder chain, and normally view controllers *aren't* in the responder > chain. > > But it does send it to the view controller! My conclusion is that you put the > view controller in the responder chain yourself, and you forgot to take it > out. This accords with #2, because it's unlikely you *retained* the view > controller before adding it to the responder chain. Ahh, this may be going in the right direction. I do: self.controlsTabBarController = [[MHControlsTabBarController alloc] init]; [self.controlsTabBarController setNextResponder:self.mainWindow.nextResponder]; [self.mainWindow setNextResponder:self.controlsTabBarController]; So I should explicitly remove self.controlsTabBarController from the responder chain in my -tearDown method? OK, in my -tearDown I've inserted [self.mainWindow setNextResponder:self.controlsTabBarController.nextResponder]; before doing [self.controlsTabBarController tearDown]; self.controlsTabBarController = nil; After a short amount of testing, I haven't had a crash. So the frequency, at least, has reduced. Maybe this even fixes the problem. Under the Zombies Instrument, I no longer get a zombie when closing documents. > > Note that I say "you", but it might of course have been done by a 3rd party > library or some code you don't have direct knowledge of. No, probably 'you' was correct here. > > Anyway I would suggest you investigate both #1 (by further examining your > code for memory management errors, and winnowing the full Instruments history > of the object) and #2 (to understand which presumably-unretained reference is > being used for the zombie messaging). > > Looking forward to your further thoughts on this, Martin ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Zombie object being messaged - why?
On Jan 25, 2013, at 22:39 , Martin Hewitson wrote: > This was held for moderation for being too large (for some reason), so I've > trimmed it and resent it. Yes, this happens sometimes when you paste something with formatting into an email as unformatted text. I don't think my post (that you're replying to here) ever got to the list, even though I tried to fix it and resend. Anyway, you've repeated the essentials. > OK, in my -tearDown I've inserted > > [self.mainWindow > setNextResponder:self.controlsTabBarController.nextResponder]; This isn't perhaps entirely safe. If anything has inserted another responder between the window and your view controller, you're going to mess up the responder chain. You should really walk the chain starting at the window, looking for the last thing before your view controller, and adjust *that* (which will generally be the window itself). >> Anyway I would suggest you investigate both #1 (by further examining your >> code for memory management errors, and winnowing the full Instruments >> history of the object) and #2 (to understand which presumably-unretained >> reference is being used for the zombie messaging). >> > Looking forward to your further thoughts on this, I think your problem is solved. :) ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com