Re: NSAttributedString crashes

2011-03-04 Thread Corbin Dunn

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

2011-03-03 Thread Matt Neuburg
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

2011-03-03 Thread Quincey Morris
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

2011-03-03 Thread Gerriet M. Denkmann

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

2011-03-03 Thread Kyle Sluder
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

2011-03-03 Thread Matt Neuburg

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

2011-03-03 Thread Graham Cox

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

2011-03-03 Thread Matt Neuburg

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

2011-03-03 Thread Andy Lee
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

2011-03-01 Thread Kyle Sluder
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

2011-03-01 Thread Gerriet M. Denkmann

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

2011-03-01 Thread Kyle Sluder
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