Re: NSAttributedString crashes
On Mar 1, 2011, at 12:45 AM, Gerriet M. Denkmann wrote: NSMutableAttributedString *attributedString = [ [ NSMutableAttributedString alloc ] initWithString: firstChar ]; [ attributedString fixFontAttributeInRange: NSMakeRange(0,[ attributedString length ]) ]; NSFont *aFont = [ attributedString attribute: NSFontAttributeName atIndex: 0 effectiveRange: NULL ]; NSLog(@%s font1 %@,__FUNCTION__, aFont);// ok NSString *fontName = [aFont fontName]; [ attributedString release ]; NSLog(@%s FontName %@,__FUNCTION__, fontName); // ok NSLog(@%s font2 %@,__FUNCTION__, aFont);// writes (null) or crashes So obviously NSAttributedString does NOT return [ [ aFont retain ] autorelease ] but just some internal pointer. Is this documented somewhere? No; you should log a bug requesting it to be documented. And/or, log a bug requesting the returned attributes be autoreleased. corbin ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Tue, 01 Mar 2011 16:15:09 +0700, Gerriet M. Denkmann gerr...@mdenkmann.de said: On 1 Mar 2011, at 15:53, Kyle Sluder wrote: On Tue, Mar 1, 2011 at 12:45 AM, Gerriet M. Denkmann gerr...@mdenkmann.de wrote: So obviously NSAttributedString does NOT return [ [ aFont retain ] autorelease ] but just some internal pointer. Is this documented somewhere? In the Memory Management Programming Guide: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAccessorMethods.html%23//apple_ref/doc/uid/TP40003539-SW6 --Kyle Sluder As far as I can see, this article talks about different ways to implement setters and getters. Do you want to imply that, whenever I get some object from AppKit, I have to retain it until I no longer need it? Would be a safe thing to do. But also tedious. And in all my past experience this was never necessary. So I thought that the Technique 1 of the linked article (returning [[someObject retain] autorelease]) was the standart practice employed by AppKit. I've been thinking about this exchange, and I would propose that you consider it like this: Suppose you've got an NSArray and you fetch its element objectAtIndex:0. And suppose you now let go of the array (release) and it is destroyed. Do you expect the fetched element to persist without your having retained it? You do not; you know darned well that a collection doesn't behave like that. The collection *owns* its elements and will release them when it is released. All you got when you called objectAtIndex:0 was a pointer. If you want a share in its ownership, you must *take* ownership. Here's another example. Suppose you've got a UIView and you ask for its subviews. Do you imagine that asking for this property gives you ownership of those subviews? You do not. Similarly for *any* property of *any* object. You *never* imagine that a fetched property is somehow magically *giving* you ownership; it's just showing you a value. So what I'm trying to show you is that when you've got an object that owns stuff, you *never* expect that that object will dispense the stuff it owns while handing you a share in ownership. You *always* take ownership if you want that stuff to persist beyond the object that dispenses them. Ownership is *never* something you are magically given. It is always something that you must take if you want it. So, what I'm saying is, an NSAttributedString is like that. When it hands you that font, it's like an NSDictionary handing you some value for a particular key. What you *can* rely on is that a ***factory method*** will hand you an autoreleased object. So, [NSArray array] hands you an autoreleased array; it won't vanish right this second, but it will vanish when your code comes to an end, unless you retain it. You may be confusing this with that. Even in that case you don't have ownership; you just have some extra persistence time while your code continues to run. And this makes sense, because there is no other owning object. Hope that helps. m. -- matt neuburg, phd = m...@tidbits.com, http://www.apeth.net/matt/ A fool + a tool + an autorelease pool = cool! Programming iOS 4! http://www.apeth.net/matt/default.html#iosbook___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Mar 3, 2011, at 10:10, Matt Neuburg wrote: What you *can* rely on is that a ***factory method*** will hand you an autoreleased object. So, [NSArray array] hands you an autoreleased array; it won't vanish right this second, but it will vanish when your code comes to an end, unless you retain it. You may be confusing this with that. Even in that case you don't have ownership; you just have some extra persistence time while your code continues to run. And this makes sense, because there is no other owning object. EXCEPT: What you say can't be literally true. In the non-factory-method case of a returned property value, you *do* have some extra persistence time, because you *must* have some extra persistence time, because you need to be able to retain the returned value before it disappears: id someValue = [someObject someProperty]; [someValue retain]; // someValue must persist at least this long Of course, in the simplest case where multiple threads aren't involved, this looks safe enough, because nothing should cause 'someValue' to dealloc before the retain. So, the question arises: how long are you permitted to go before you need to do the retain? AFAIK there's no actual answer to that question, but the pragmatic answer has always been: until the next drain of an autorelease pool that might contain the object (that is, often, until you return to the main event loop), and that's a little hard to predict in the general case that might involve local autorelease pools. What I'm trying to say is that deciding whether to be safe/tedious is, theoretically, guesswork. In practice, the usual heuristic is to assume a retained-autoreleased object, and to fix the crashes on a case by case basis -- which is what Gerriet just had to do. EXCEPT: Suppose you've got an NSArray and you fetch its element objectAtIndex:0. And suppose you now let go of the array (release) and it is destroyed. Do you expect the fetched element to persist without your having retained it? You do not; you know darned well that a collection doesn't behave like that. The collection *owns* its elements and will release them when it is released. All you got when you called objectAtIndex:0 was a pointer. If you want a share in its ownership, you must *take* ownership. And the one common zero-extra-persistence-time case that you didn't quite mention: id someValue = [someArray objectAtIndex: 0]; [someArray removeObjectAtIndex: 0]; [someValue retain]; // too late! I think both of these are essentially different from Gerriet's case, because there is an obvious change-of-ownership event between getting the non-retained pointer and retaining it. The only real connection between the two scenarios is that you end up with a pointer to a possibly dead object, unless you take care. AND: Things are both better and worse under garbage collection. Worse, because there is no extra persistence time, because the GC thread could run at any moment. Better, because the the compile-time scoping of variables *usually* creates the effect of extra persistence time, until the run-time equivalent of the } of the block containing their declaration. Except when optimization shortens the effective scope. But that's a different discussion. ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On 4 Mar 2011, at 01:10, Matt Neuburg wrote: On Tue, 01 Mar 2011 16:15:09 +0700, Gerriet M. Denkmann gerr...@mdenkmann.de said: On 1 Mar 2011, at 15:53, Kyle Sluder wrote: On Tue, Mar 1, 2011 at 12:45 AM, Gerriet M. Denkmann gerr...@mdenkmann.de wrote: So obviously NSAttributedString does NOT return [ [ aFont retain ] autorelease ] but just some internal pointer. Is this documented somewhere? In the Memory Management Programming Guide: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAccessorMethods.html%23//apple_ref/doc/uid/TP40003539-SW6 --Kyle Sluder As far as I can see, this article talks about different ways to implement setters and getters. Do you want to imply that, whenever I get some object from AppKit, I have to retain it until I no longer need it? Would be a safe thing to do. But also tedious. And in all my past experience this was never necessary. So I thought that the Technique 1 of the linked article (returning [[someObject retain] autorelease]) was the standart practice employed by AppKit. I've been thinking about this exchange, and I would propose that you consider it like this: Suppose you've got an NSArray and you fetch its element objectAtIndex:0. And suppose you now let go of the array (release) and it is destroyed. Do you expect the fetched element to persist without your having retained it? You do not; you know darned well that a collection doesn't behave like that. The collection *owns* its elements and will release them when it is released. All you got when you called objectAtIndex:0 was a pointer. If you want a share in its ownership, you must *take* ownership. Here's another example. Suppose you've got a UIView and you ask for its subviews. Do you imagine that asking for this property gives you ownership of those subviews? You do not. Similarly for *any* property of *any* object. You *never* imagine that a fetched property is somehow magically *giving* you ownership; it's just showing you a value. So what I'm trying to show you is that when you've got an object that owns stuff, you *never* expect that that object will dispense the stuff it owns while handing you a share in ownership. You *always* take ownership if you want that stuff to persist beyond the object that dispenses them. Ownership is *never* something you are magically given. It is always something that you must take if you want it. Yes, I fully agree. But, taking my original example: NSAttributedString * attributedString = ... NSFont *aFont = [ attributedString attribute: NSFontAttributeName atIndex: 0 effectiveRange: NULL ]; NSString *fontName = [aFont fontName]; [ attributedString release ]; Now aFont no longer exists. So fontName, being a property of the no longer existing aFont, should have vanished also, shouldn't it? But in my case, fontName is still valid. Maybe the fontName method really returns [[fontName retain]autorelease] (as I wrongly assumed all methods did) or some magical entity keeps a handle on all font names, or this name is a constant string decared in AppKit, or whatever. But this did add to my confusion. Kind regards, Gerriet. ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Thu, Mar 3, 2011 at 4:20 PM, Gerriet M. Denkmann gerr...@mdenkmann.de wrote: But, taking my original example: NSAttributedString * attributedString = ... NSFont *aFont = [ attributedString attribute: NSFontAttributeName atIndex: 0 effectiveRange: NULL ]; NSString *fontName = [aFont fontName]; [ attributedString release ]; Now aFont no longer exists. So fontName, being a property of the no longer existing aFont, should have vanished also, shouldn't it? Replace should with could. The point is that there's no guarantee, and you need to be prepared for the case where it does. --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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Mar 3, 2011, at 4:35 PM, Kyle Sluder wrote: On Thu, Mar 3, 2011 at 4:20 PM, Gerriet M. Denkmann gerr...@mdenkmann.de wrote: But, taking my original example: NSAttributedString * attributedString = ... NSFont *aFont = [ attributedString attribute: NSFontAttributeName atIndex: 0 effectiveRange: NULL ]; NSString *fontName = [aFont fontName]; [ attributedString release ]; Now aFont no longer exists. So fontName, being a property of the no longer existing aFont, should have vanished also, shouldn't it? Replace should with could. The point is that there's no guarantee, and you need to be prepared for the case where it does. And anyway the argument, as specifically posed, is specious, because NSString is a very, very special case. Memory management for strings is utterly different from memory management for a normal object. Most strings are way over-retained and *never* vanish. Indeed, it is quite difficult to generate a string that *does* vanish if no one retains it. You can do it, but you have to hunt around for a while to figure out how. So arguing by analogy with what an NSString does cuts no ice whatever. Having said all of that, the OP should feel free to file a bug. I've recently filed about a memory leak in connection with NSMutableAttributedString, and have had this acknowledged as a known issue. So the idea that there might be something a bit funny with memory management in connection with NSAttributedString is not unreasonable. m. ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On 04/03/2011, at 11:54 AM, Matt Neuburg wrote: because NSString is a very, very special case. Memory management for strings is utterly different from memory management for a normal object Is it? Are you basing this on your observations, or on some documentation? I don't see this though I haven't gone out of my way to look for it. There is no reason I've ever found to treat NSString as a special case, and it doesn't sound right to me that strings are effectively never deallocated, which seems to be what you're implying. That would be a leak of a rather major order, wouldn't it? --Graham ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Mar 3, 2011, at 7:32 PM, Graham Cox wrote: On 04/03/2011, at 11:54 AM, Matt Neuburg wrote: because NSString is a very, very special case. Memory management for strings is utterly different from memory management for a normal object Is it? Are you basing this on your observations, or on some documentation? Well, I may have put it rather too strongly - string literals are special, is what I meant. But many strings start life as a literal. I'm not saying one should *treat* them differently - indeed, doing that is a good way to get into trouble. I'm just saying that if you peek at the man behind the curtain (the retain count) they can be surprising - like the retain count for stringWithString:@hello. At one point I needed to make a string with a normal retain count (for a teaching example) and had quite a bit of trouble working out how to do it. m.___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Mar 3, 2011, at 1:10 PM, Matt Neuburg wrote: So what I'm trying to show you is that when you've got an object that owns stuff, you *never* expect that that object will dispense the stuff it owns while handing you a share in ownership. I would argue it's irrelevant whether the dispensing object owns what it dispenses. True, you'll have a pretty good idea whether it does or not, but not always. Suppose I have NSString *fn = [aPerson fullName]; I don't necessarily know whether aPerson owns the object referenced by fn, and I don't care. fullName does not contain new, alloc, or copy, so the memory management rules say I must retain fn if I want it to stick around. As for what stick around means... You *always* take ownership if you want that stuff to persist beyond the object that dispenses them. ...I don't think I've ever heard the phrasing, beyond the object that dispenses them. We've been conditioned to think we have extra persistence time at least up to the next run loop iteration. I think this stronger assertion is better and addresses the issue at hand. --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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Tue, Mar 1, 2011 at 12:45 AM, Gerriet M. Denkmann gerr...@mdenkmann.de wrote: So obviously NSAttributedString does NOT return [ [ aFont retain ] autorelease ] but just some internal pointer. Is this documented somewhere? In the Memory Management Programming Guide: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAccessorMethods.html%23//apple_ref/doc/uid/TP40003539-SW6 --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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On 1 Mar 2011, at 15:53, Kyle Sluder wrote: On Tue, Mar 1, 2011 at 12:45 AM, Gerriet M. Denkmann gerr...@mdenkmann.de wrote: So obviously NSAttributedString does NOT return [ [ aFont retain ] autorelease ] but just some internal pointer. Is this documented somewhere? In the Memory Management Programming Guide: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAccessorMethods.html%23//apple_ref/doc/uid/TP40003539-SW6 --Kyle Sluder As far as I can see, this article talks about different ways to implement setters and getters. Do you want to imply that, whenever I get some object from AppKit, I have to retain it until I no longer need it? Would be a safe thing to do. But also tedious. And in all my past experience this was never necessary. So I thought that the Technique 1 of the linked article (returning [[someObject retain] autorelease]) was the standart practice employed by AppKit. Kind regards, Gerriet. ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSAttributedString crashes
On Tue, Mar 1, 2011 at 1:15 AM, Gerriet M. Denkmann gerr...@mdenkmann.de wrote: As far as I can see, this article talks about different ways to implement setters and getters. Do you want to imply that, whenever I get some object from AppKit, I have to retain it until I no longer need it? You got the font from an accessor on the attributed string. You released the attributed string. Therefore, your reference to the font might no longer be valid. This is what Option 3 describes. Would be a safe thing to do. But also tedious. And in all my past experience this was never necessary. Probably because you either didn't explicitly release the object whose accessor you called (you autoreleased it or never had an owning reference), or the accessor covered your butt. So I thought that the Technique 1 of the linked article (returning [[someObject retain] autorelease]) was the standart practice employed by AppKit. Nope, otherwise there'd be no sense in documenting the others. They'd just document the one they used and tell you to do the same. --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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com