Re: NSDictionary trouble

2010-01-20 Thread Ken Thomases
On Jan 20, 2010, at 5:22 AM, Jens Miltner wrote:

> Am 20.01.2010 um 11:34 schrieb Jeremy Pereira:
> 
>> On 19 Jan 2010, at 23:06, Jens Alfke wrote:
>> 
>>> On Jan 19, 2010, at 10:46 AM, Kirk Kerekes wrote:
>>> 
 NSDictionary will use almost any object as a key:
 
 From the docs:
 "In general, a key can be any object (provided that it conforms to the 
 NSCopying protocol...)"
 
 -- and if it is an immutable object, that -copy is just a -retain.
>>> 
>>> Yes, but he said he wants to use a view as the key. Views are not 
>>> immutable, and do copy themselves in response to -copy. Having a dictionary 
>>> whose key objects are copies of your live views is not very useful. 
>>> (Especially since the copied view will have a different hashcode from the 
>>> original one, so you can't even look it up using the original view 
>>> anymore...)
>> 
>> Well he could write a category to give him an object that satisfies all the 
>> criteria e.g (written in Mail).
>> 
>> 
>> @interface NSView(DictionaryKey)
>> 
>> -(NSNumber*) dictionaryKey;
>> 
>> @end
>> 
>> @implementation NSView(DictionaryKey)
>> 
>> -(NSNumber*) dictionaryKey
>> {
>>  return [NSNumber numberWithUnsignedLongLong: (unsigned long long) self];
>> }
> 
> Slightly safer (because it does not make explicit assumptions about pointer 
> sizes):
> 
> -(id) dictionaryKey
> {
>   return [NSString stringWithFormat:@"%p", self];
> }
> 
> 
> Sorry, couldn't resist ;-)

Um, if you're going to go that route, use +[NSValue 
valueWithNonretainedObject:].  Playing with strings or NSNumbers is doing it 
the hard way.  But, if you can use it, NSMapTable (as mentioned previously) is 
probably more appropriate.

Regards,
Ken

___

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: NSDictionary trouble

2010-01-20 Thread Jens Miltner


Am 20.01.2010 um 11:34 schrieb Jeremy Pereira:



On 19 Jan 2010, at 23:06, Jens Alfke wrote:



On Jan 19, 2010, at 10:46 AM, Kirk Kerekes wrote:


NSDictionary will use almost any object as a key:

From the docs:
"In general, a key can be any object (provided that it conforms to  
the NSCopying protocol...)"


-- and if it is an immutable object, that -copy is just a -retain.


Yes, but he said he wants to use a view as the key. Views are not  
immutable, and do copy themselves in response to -copy. Having a  
dictionary whose key objects are copies of your live views is not  
very useful. (Especially since the copied view will have a  
different hashcode from the original one, so you can't even look it  
up using the original view anymore...)


Well he could write a category to give him an object that satisfies  
all the criteria e.g (written in Mail).



@interface NSView(DictionaryKey)

-(NSNumber*) dictionaryKey;

@end

@implementation NSView(DictionaryKey)

-(NSNumber*) dictionaryKey
{
	return [NSNumber numberWithUnsignedLongLong: (unsigned long long)  
self];

}


Slightly safer (because it does not make explicit assumptions about  
pointer sizes):


-(id) dictionaryKey
{
return [NSString stringWithFormat:@"%p", self];
}


Sorry, couldn't resist ;-)



___

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: NSDictionary trouble

2010-01-20 Thread Jeremy Pereira

On 19 Jan 2010, at 23:06, Jens Alfke wrote:

> 
> On Jan 19, 2010, at 10:46 AM, Kirk Kerekes wrote:
> 
>> NSDictionary will use almost any object as a key:
>> 
>> From the docs:
>> "In general, a key can be any object (provided that it conforms to the 
>> NSCopying protocol...)"
>> 
>> -- and if it is an immutable object, that -copy is just a -retain.
> 
> Yes, but he said he wants to use a view as the key. Views are not immutable, 
> and do copy themselves in response to -copy. Having a dictionary whose key 
> objects are copies of your live views is not very useful. (Especially since 
> the copied view will have a different hashcode from the original one, so you 
> can't even look it up using the original view anymore...)

Well he could write a category to give him an object that satisfies all the 
criteria e.g (written in Mail).


@interface NSView(DictionaryKey)

-(NSNumber*) dictionaryKey;

@end

@implementation NSView(DictionaryKey)

-(NSNumber*) dictionaryKey
{
return [NSNumber numberWithUnsignedLongLong: (unsigned long long) self];
}

@end

Then he could do things like:

[myDictionary setObject: foo forKey: [myView dictionaryKey]];

...

bar = [myDictionary objectForKey [myView dictionaryKey]]; 

The above creates a key based on the address of the NSView.

> 
> —Jens___
> 
> 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/adc%40jeremyp.net
> 
> This email sent to a...@jeremyp.net


__
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
__
___

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: NSDictionary trouble

2010-01-19 Thread Ken Thomases
On Jan 19, 2010, at 10:47 PM, Jeff Laing wrote:

> I'm assuming you are saying 'don't use the convenience methods because the 
> autorelease pool won't empty quickly enough'. Certainly Ken said it, though 
> he seemed to assume that there was only one pool, that people would not be 
> creating their own in their known trouble-spots.

I didn't make that assumption.  In fact, you quote me below referring to the 
"current pool".  The word "current" is in there specifically because I kept the 
possibility of nested pools in mind.

I also didn't say "don't use ...".  I was explaining Apple's recommendation, to 
the best of my understanding.

> Ken Thomases wrote:
>> The autorelease pool is convenient and in some cases necessary, but it
>> does come at some cost.  It has some overhead in terms of time and
>> memory, plus it tends to increase the peak memory usage of your
>> program.  (Over time, assuming you've got all your memory management
>> correct, a program's memory usage will come out the same, but
>> autoreleased objects accumulate over the lifetime of the current pool,
>> causing spiky memory usage.)
> 
> But implicit in that seems to be that -[NSDictionary initWithObjectsAndKeys:] 
> won't add to the auto-release pool and I don't see where that's a valid 
> assumption (or at least a documented assumption).

I didn't make that assumption, either, and you're correct that doing so is 
unsupportable.  However, the choice you make about which methods to invoke 
imposes restrictions on the frameworks.

If you use convenience constructors, you're essentially requiring the use of 
autoreleased objects.  (Obligatory caveat: not all results from convenience 
constructors are necessarily autoreleased.  This discussion is about those 
cases where they are.)  If you use alloc+init, you at least allow the 
frameworks to minimize use of autoreleased objects.  Whether or not the 
frameworks take the opportunity is beyond your control or caring. Given that 
it's Apple who are making the recommendation, one can hope the frameworks are 
coded to follow it.

I also pointed out that this is a matter of judgments about trade-offs and a 
recommendation (not a rule) particular to a highly-constrained environment.  
Personally, I don't develop for the iPhone and so the memory usage side of that 
tradeoff doesn't weigh as heavily for me.

Cheers,
Ken

___

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: NSDictionary trouble

2010-01-19 Thread mmalc Crawford

On Jan 19, 2010, at 8:47 pm, Jeff Laing wrote:

> I wrote:
>>> No, you should just *retain* the result of dictionaryWithCapacity.
> 
> mmalc wrote:
>> No, you shouldn't.
> With all due respect, why not?
> 

Because it's difficult to imagine a common situation in which your advice will 
be valid, for example:

NSMutableDictionary *dict = [NSMutableDictionary 
dictionaryWithCapacity:x];
// Add to the dictionary.
myInstanceVariable = [dict retain];
Wrong, because you're setting an instance variable directly instead of using an 
accessor.

NSMutableDictionary *dict = [[NSMutableDictionary 
dictionaryWithCapacity:x] retain];
// Use the dictionary.
[dict release];
Retaining the dictionary is pointless.


> Apple gives us all those convenience methods but you say we shouldn't use 
> them?
> 
Please don't misrepresent what I wrote. I didn't say that. There are situations 
in which the convenience API is useful and not discouraged. In particular, for 
example, if you're creating a dictionary as a return value from a method, then 
it's perfectly reasonable to use a convenience method:

- (NSDictionary *)dictionaryRepresentation {

NSMutableDictionary *dict = [NSMutableDictionary 
dictionaryWithCapacity:5];
// Use the dictionary.
return dict;
}

(Also if you're using garbage collection, any of the convenience methods are 
perfectly reasonable.)

In most other cases, however, Jens and Ken have already addressed the principal 
issue: performance. You don't want to needlessly prolong the lifetime of 
objects.


>> If you want to assign the dictionary to an instance variable, you
>> should use an accessor method. In this case, it's still better to use
>> alloc/init then release the dictionary when you've finished with it.
> That's seems a really aberrant case, where you are creating an empty 
> dictionary with a nominated capacity.  I can't visualize a case where you 
> would do such a thing, outside of the initialiser.
> 

This pattern is shown commonly in iPhone sample code:

NSMutableDictionary *aDictionary = [[NSMutableDictionary alloc] 
initWithCapacity:x]
// Add to the dictionary.
self.dictionary = aDictionary;
[aDictionary release];

> There are cases like the NSFileManager where you need to pass in a dictionary 
> of options that describe the directory being created (for example) - should I 
> really be creating temporary variables for those, or using the convenience 
> methods (dictionaryWithObject:forKey:)?
> 

The same applies as above.
Following best practices, you should use alloc/init+release. How important this 
is to adhere to depends on how performance-sensitive your code and platform 
are...
To reiterate Jens' succinct formula:
Convenience ≠ performance.

mmalc






___

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: NSDictionary trouble

2010-01-19 Thread Jens Alfke

On Jan 19, 2010, at 8:47 PM, Jeff Laing wrote:

> With all due respect, why not?  Apple gives us all those convenience methods 
> but you say we shouldn't use them?

Convenience ≠ performance.

The autoreleased factory methods are very convenient when you're using the 
result temporarily, so you don't have to remember to release it. But when the 
point of the call is to get a reference, and you're not releasing right away 
anyway, it's just as easy and more efficient to use alloc/init.

—Jens___

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: NSDictionary trouble

2010-01-19 Thread Jeff Laing
> >> Yes, and it autoreleases it too. :-o That means it'll conveniently be
> >> released later on, which is exactly what you're running into. If you
> >> want to keep a reference to the dictionary, you should call alloc and
> >> init yourself.

I wrote:
> > No, you should just *retain* the result of dictionaryWithCapacity.

mmalc wrote:
> No, you shouldn't.

With all due respect, why not?  Apple gives us all those convenience methods 
but you say we shouldn't use them?

(Note, my first kneejerk response was of course because I'm sure you'll find 
Apple docs that say explicitly "if you want to keep a reference to , you 
should retain it" whereas it's unlikely you'll find anything that says "if you 
want to keep a reference to , you're probably using the wrong design 
pattern")

(Oh, and, dictionaryWithCapacity: is really not one I'd get in a fuss about.  
But some of the other dictionaryWithObjects: convenience methods are too damned 
handy to lose.  I just don't think that "best practice" should be something 
that changes depending on which particular convenience method you are talking 
about)

> If you're writing an init method and want to assign the dictionary to
> an instance variable, you should use alloc/init.
> 
> If you want to assign the dictionary to an instance variable, you
> should use an accessor method. In this case, it's still better to use
> alloc/init then release the dictionary when you've finished with it.

That's seems a really aberrant case, where you are creating an empty dictionary 
with a nominated capacity.  I can't visualize a case where you would do such a 
thing, outside of the initialiser.

> If you want to create the dictionary, use it temporarily, then forget
> about it, then dictionaryWithCapacity is OK, but again (particularly on
> iPhone) best practice is still to use alloc/init+release.

There are cases like the NSFileManager where you need to pass in a dictionary 
of options that describe the directory being created (for example) - should I 
really be creating temporary variables for those, or using the convenience 
methods (dictionaryWithObject:forKey:)?

I'm assuming you are saying 'don't use the convenience methods because the 
autorelease pool won't empty quickly enough'. Certainly Ken said it, though he 
seemed to assume that there was only one pool, that people would not be 
creating their own in their known trouble-spots.

Ken Thomases wrote:
> The autorelease pool is convenient and in some cases necessary, but it
> does come at some cost.  It has some overhead in terms of time and
> memory, plus it tends to increase the peak memory usage of your
> program.  (Over time, assuming you've got all your memory management
> correct, a program's memory usage will come out the same, but
> autoreleased objects accumulate over the lifetime of the current pool,
> causing spiky memory usage.)

But implicit in that seems to be that -[NSDictionary initWithObjectsAndKeys:] 
won't add to the auto-release pool and I don't see where that's a valid 
assumption (or at least a documented assumption).  If you look at some of the 
stack traces in Instruments, you find things being created way down in the 
bowels of the frameworks that you wouldn't necessarily expect.  (Date 
Formatter, I'm looking at you)

I'm increasingly of the opinion that to be properly paranoid (that is, to not 
assume anything about the behavior of 3rd party (including Apple) classes) and 
survive in the limited memory world of the iPhone, you should be writing your 
initialisers like this:

- (id)initLikeJeffThinksYouShould
{
if (self = [super init]) {
// Assume incompetence in others and you'll never be disappointed, only 
pleasantly surprised.
NSAutoreleasePool *pool = [NSAutorelease pool new];
_var = [[SomeoneElsesClass someMethodWhichMightFillThePool] retain];
[pool drain];
}
return(self);
}

That's all putting aside that by calling dictionaryWithCapacity: it seems to me 
that the NSMutableDictionary framework has more chance of re-using one it had 
lying around in some cache - yes, initWithCapacity: could do that as well, but 
there would still be the memory-churn expense of the alloc/release that would 
not be needed by dictionaryWithCapacity

It might not do it today but if I give the system the clearest possible 
indication of what I want (and not just the steps I think it should go 
through), I leave more scope for clever software engineers to add extra 
optimizations under the covers in future revisions.

___

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: NSDictionary trouble

2010-01-19 Thread Ken Thomases
On Jan 19, 2010, at 9:21 PM, Shawn Rutledge wrote:

> On Tue, Jan 19, 2010 at 7:01 PM, mmalc Crawford  wrote:
>>> No, you should just *retain* the result of dictionaryWithCapacity.
>>> 
>> No, you shouldn't.
>> 
>> If you're writing an init method and want to assign the dictionary to an 
>> instance variable, you should use alloc/init.
> 
> Why?

The autorelease pool is convenient and in some cases necessary, but it does 
come at some cost.  It has some overhead in terms of time and memory, plus it 
tends to increase the peak memory usage of your program.  (Over time, assuming 
you've got all your memory management correct, a program's memory usage will 
come out the same, but autoreleased objects accumulate over the lifetime of the 
current pool, causing spiky memory usage.)

In general, it's always good to be aware of such trade-offs and make judgments 
with them in mind.  In a highly constrained environment like the iPhone, the 
recommendation is to avoid the autorelease pool in the simple cases where it's 
easy to do so.  Like, the difference between the following:

someIvar = [[NSMutableDictionary dictionaryWithCapacity:5] retain];

and

someIvar = [[NSMutableDictionary alloc] initWithCapacity:5];

is not hard on the developer, but keeps usage of the autorelease pool to a 
minimum.

Regards,
Ken

___

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: NSDictionary trouble

2010-01-19 Thread Shawn Rutledge
On Tue, Jan 19, 2010 at 7:01 PM, mmalc Crawford  wrote:
>> No, you should just *retain* the result of dictionaryWithCapacity.
>>
> No, you shouldn't.
>
> If you're writing an init method and want to assign the dictionary to an 
> instance variable, you should use alloc/init.

Why?
___

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: NSDictionary trouble

2010-01-19 Thread mmalc Crawford

On Jan 19, 2010, at 5:50 pm, Jeff Laing wrote:

>> Yes, and it autoreleases it too. :-o That means it'll conveniently be
>> released later on, which is exactly what you're running into. If you
>> want to keep a reference to the dictionary, you should call alloc and
>> init yourself.
> 
> No, you should just *retain* the result of dictionaryWithCapacity.
> 
No, you shouldn't.

If you're writing an init method and want to assign the dictionary to an 
instance variable, you should use alloc/init.

If you want to assign the dictionary to an instance variable, you should use an 
accessor method. In this case, it's still better to use alloc/init then release 
the dictionary when you've finished with it.

If you want to create the dictionary, use it temporarily, then forget about it, 
then dictionaryWithCapacity is OK, but again (particularly on iPhone) best 
practice is still to use alloc/init+release.

mmalc

___

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: NSDictionary trouble

2010-01-19 Thread Jeff Laing
> > I think dictionaryWithCapacity should both alloc and init it, right?
> 
> Yes, and it autoreleases it too. :-o That means it'll conveniently be
> released later on, which is exactly what you're running into. If you
> want to keep a reference to the dictionary, you should call alloc and
> init yourself.

No, you should just *retain* the result of dictionaryWithCapacity.
___

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: NSDictionary trouble

2010-01-19 Thread Jean-Daniel Dupas

Le 20 janv. 2010 à 00:18, Kyle Sluder a écrit :

> On Tue, Jan 19, 2010 at 3:09 PM, Shawn Rutledge
>  wrote:
>> Well yeah, that's one of the reasons java.lang.String is immutable.
>> But it helps that java.lang.Object has both hashCode and equals, so
>> any object can be put into a collection that depends on those... you
>> just have the option of improving the implementation of those for
>> better hash distribution, comparing two objects by content rather than
>> reference location, etc.  I just wanted a hashtable that uses keys by
>> pointer rather than expecting to copy them.  Nice to know that copying
>> protocol doesn't mean you have to actually copy it though.
> 
> NSObject has -hash and -isEqual:. If you want a pointer-based
> dictionary, create a CFDictionary with the appropriate options, and
> cast it to NSDictionary* (read the documentation on Toll-Free Bridging
> to see why this is possible).

An other solution can be to use NSMapTable class. I prefer it to CFDictionary 
because the later is not really toll-free bridged when using custom key/value 
callbacks.
Even with a NULL or CFType Key callback, if you use NSMutableDictionary 
methods, is will try to copy the keys. 

>> As for C++, you can use template containers to store either pointers
>> or copies of objects, whichever you like.
> 
> STL containers are far more explicit about their internal behavior.
> It's possible to write a collection class that has the same
> restrictions as NSDictionary.
> 
> --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/devlists%40shadowlab.org
> 
> This email sent to devli...@shadowlab.org
> 

-- Jean-Daniel




___

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: NSDictionary trouble

2010-01-19 Thread Kyle Sluder
On Tue, Jan 19, 2010 at 3:09 PM, Shawn Rutledge
 wrote:
> Well yeah, that's one of the reasons java.lang.String is immutable.
> But it helps that java.lang.Object has both hashCode and equals, so
> any object can be put into a collection that depends on those... you
> just have the option of improving the implementation of those for
> better hash distribution, comparing two objects by content rather than
> reference location, etc.  I just wanted a hashtable that uses keys by
> pointer rather than expecting to copy them.  Nice to know that copying
> protocol doesn't mean you have to actually copy it though.

NSObject has -hash and -isEqual:. If you want a pointer-based
dictionary, create a CFDictionary with the appropriate options, and
cast it to NSDictionary* (read the documentation on Toll-Free Bridging
to see why this is possible).

> As for C++, you can use template containers to store either pointers
> or copies of objects, whichever you like.

STL containers are far more explicit about their internal behavior.
It's possible to write a collection class that has the same
restrictions as NSDictionary.

--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: NSDictionary trouble

2010-01-19 Thread Shawn Rutledge
On Tue, Jan 19, 2010 at 2:33 PM, Jeremy Pereira  wrote:
>
> On 19 Jan 2010, at 16:53, Shawn Rutledge wrote:
>
>>  I'm accustomed to
>> things like Qt and Java where hashtables can contain anything for both
>> key and value.
>
> This is not true (at least for Java and probably for QT for the same reason). 
>  From the API docs for the Map abstract class:
>
> "Note: great care must be exercised if mutable objects are used as map keys. 
> The behavior of a map is not specified if the value of an object is changed 
> in a manner that affects equals comparisons while the object is a key in the 
> map. "

Well yeah, that's one of the reasons java.lang.String is immutable.
But it helps that java.lang.Object has both hashCode and equals, so
any object can be put into a collection that depends on those... you
just have the option of improving the implementation of those for
better hash distribution, comparing two objects by content rather than
reference location, etc.  I just wanted a hashtable that uses keys by
pointer rather than expecting to copy them.  Nice to know that copying
protocol doesn't mean you have to actually copy it though.

As for C++, you can use template containers to store either pointers
or copies of objects, whichever you like.
___

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: NSDictionary trouble

2010-01-19 Thread Jens Alfke


On Jan 19, 2010, at 10:46 AM, Kirk Kerekes wrote:


NSDictionary will use almost any object as a key:

From the docs:
"In general, a key can be any object (provided that it conforms to  
the NSCopying protocol...)"


-- and if it is an immutable object, that -copy is just a -retain.


Yes, but he said he wants to use a view as the key. Views are not  
immutable, and do copy themselves in response to -copy. Having a  
dictionary whose key objects are copies of your live views is not very  
useful. (Especially since the copied view will have a different  
hashcode from the original one, so you can't even look it up using the  
original view anymore...)


—Jens___

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: NSDictionary trouble

2010-01-19 Thread Jens Alfke


On Jan 19, 2010, at 2:57 PM, Shawn Rutledge wrote:


I think dictionaryWithCapacity should both alloc and init it, right?


Yes, and it autoreleases it too. :-o That means it'll conveniently be  
released later on, which is exactly what you're running into. If you  
want to keep a reference to the dictionary, you should call alloc and  
init yourself.


Sounds like you need to read over the memory management rules again :)  
Remember the cardinal rule: The only methods that return references  
you own and have to release are "alloc", "copy", "mutableCopy", "new",  
and of course "retain".


—Jens___

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: NSDictionary trouble

2010-01-19 Thread Graham Cox

On 20/01/2010, at 9:57 AM, Shawn Rutledge wrote:

> I think dictionaryWithCapacity should both alloc and init it, right?


Why do you think that?

I repeat: "You MUST learn the memory management rules and have them down pat so 
you can write correctly managed code without having to really think about 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: NSDictionary trouble

2010-01-19 Thread Kyle Sluder
On Tue, Jan 19, 2010 at 2:57 PM, Shawn Rutledge
 wrote:
> I think dictionaryWithCapacity should both alloc and init it, right?

Please stop making conjectures. The documentation explains all of this.

--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: NSDictionary trouble

2010-01-19 Thread Shawn Rutledge
On Tue, Jan 19, 2010 at 2:38 PM, Graham Cox  wrote:
>
> On 20/01/2010, at 5:33 AM, Shawn Rutledge wrote:
>
>> I forgot to mention, another problem I ran into was that my dictionary
>> is a member variable of my UIViewController, I inited it in
>> initWithNibName, then later when I go to use it in another member
>> function, I found that it had been garbage-collected.  I used other
>> member variables the same way, but only the dictionary got
>> garbage-collected.  So I fixed it by doing [myDict retain]; in the
>> initWithNibName, but didn't understand why such a thing should be
>> necessary.
>
>
> Uh-oh, category error.
>
> UIViewController is an iPhone class, therefore you must be programming on 
> iPhone, right? Which does not have garbage collection.

Oops, I guess you're right.  I'm a n00b both on Objective-C and the
iphone (obviously).

> Therefore your assumptions about what is happening are wrong. You MUST learn 
> the memory management rules and have them down pat so you can write correctly 
> managed code without having to really think about it.

Yes I will read more about that.  Anyway, the NSMutableDictionary*
member variable was inited fine, I can see that if I set a breakpoint
in the VC's init method, but by the time I use it in another member
function, it's pointing to unallocated memory.  I verified that with
the NSZombie trick.  But retaining the dictionary fixed it.  Any idea
why?

I think dictionaryWithCapacity should both alloc and init it, right?
___

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: NSDictionary trouble

2010-01-19 Thread Graham Cox

On 20/01/2010, at 5:33 AM, Shawn Rutledge wrote:

> I forgot to mention, another problem I ran into was that my dictionary
> is a member variable of my UIViewController, I inited it in
> initWithNibName, then later when I go to use it in another member
> function, I found that it had been garbage-collected.  I used other
> member variables the same way, but only the dictionary got
> garbage-collected.  So I fixed it by doing [myDict retain]; in the
> initWithNibName, but didn't understand why such a thing should be
> necessary.


Uh-oh, category error.

UIViewController is an iPhone class, therefore you must be programming on 
iPhone, right? Which does not have garbage collection. Therefore your 
assumptions about what is happening are wrong. You MUST learn the memory 
management rules and have them down pat so you can write correctly managed code 
without having to really think about 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: NSDictionary trouble

2010-01-19 Thread Jeremy Pereira

On 19 Jan 2010, at 16:53, Shawn Rutledge wrote:

>  I'm accustomed to
> things like Qt and Java where hashtables can contain anything for both
> key and value. 

This is not true (at least for Java and probably for QT for the same reason).  
From the API docs for the Map abstract class:

"Note: great care must be exercised if mutable objects are used as map keys. 
The behavior of a map is not specified if the value of an object is changed in 
a manner that affects equals comparisons while the object is a key in the map. "

From the docs for Object.hashCode()

"Whenever it is invoked on the same object more than once during an execution 
of a Java application, the hashCode method must consistently return the same 
integer, provided no information used in equals comparisons on the object is 
modified."

The Cocoa "restriction" on keys actually makes things a little easier.  For 
instance, you can use NSMutableString as a key in an NSDictionary with no 
problems.  However, if you try to use a StringBuffer or StringBuilder as a key 
in a Java map, you won't get the "natural" behaviour - two distinct 
StringBuffers with the same character sequence in them do not compare equal and 
if you override equals() in a subclass to make sure they do, you'd better not 
change a StringBuffer that happens to be a key in a 
map.___

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: NSDictionary trouble

2010-01-19 Thread Kirk Kerekes
> I wish NSDictionary (NSMutableDictionary actually) could handle
> arbitrary mappings of one type of object to another, without copying
> the keys.  A string makes a good key most of the time but what about
> the case where you want to do the reverse mapping, to find the string
> which you have associated with a particular object?  I'm accustomed to
> things like Qt and Java where hashtables can contain anything for both
> key and value.  Is there an alternative which does work that way?  I
> didn't try CFDictionary yet; is that appropriate for an iPhone app?

NSDictionary will use almost any object as a key:

From the docs:
"In general, a key can be any object (provided that it conforms to the 
NSCopying protocol...)"

 -- and if it is an immutable object, that -copy is just a -retain.

Only if you want to use KVC with the NSDictionary to the keys need to be 
strings.

___

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: NSDictionary trouble

2010-01-19 Thread Sixten Otto
On Tue, Jan 19, 2010 at 1:24 PM, Jens Alfke  wrote:
> On Jan 19, 2010, at 8:53 AM, Shawn Rutledge wrote:
>> I didn't try CFDictionary yet; is that appropriate for an iPhone app?
>
> But try NSMapTable first. It's sort of halfway between the two — it's an
> Objective-C class but it has greater flexibility in what it can store and
> how it stores it.

Is NSMapTable available in Cocoa Touch? I was under the impression
that that was Mac-only.

Sixten
___

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: NSDictionary trouble

2010-01-19 Thread Shawn Rutledge
On Tue, Jan 19, 2010 at 11:24 AM, Jens Alfke  wrote:
>
> On Jan 19, 2010, at 8:53 AM, Shawn Rutledge wrote:
>
>> I wish NSDictionary (NSMutableDictionary actually) could handle
>> arbitrary mappings of one type of object to another, without copying
>> the keys.
>
> It can. If you have a custom class you want to be able to use as a
> dictionary key without copying, then make it implement the NSCopying
> protocol and add this method:
>        - (id) copyWithZone: (NSZone*)zone {
>                return [self retain];
>        }
> This enables -copy but turns it into a no-op that returns the original
> object. (This is perfectly kosher. Most immutable Foundation objects do the
> same thing, i.e. copying an immutable NSString returns the same object.)

OK thanks, that's good to know.  However in this case I wanted to add
NSSwitch objects to the dictionary.  So it would have to be a subclass
then I guess.

> Of course you also have to implement -hash and -isEqual: to make your class
> play nicely with dictionaries. Make sure these have immutable semantics: if
> the values returned by these can ever change, you'll screw up any dictionary
> or set the object is in.
>
>> I didn't try CFDictionary yet; is that appropriate for an iPhone app?
>
> Yes, you can use CF. Remember that a CFXXXRef is the same as an NSXXX*, you
> can just typecast between them. If you create a CFDictionary you'll have to
> define your own callbacks, and make the copy callback just retain the
> object.
>
> But try NSMapTable first. It's sort of halfway between the two — it's an
> Objective-C class but it has greater flexibility in what it can store and
> how it stores it.

Oh that looks good too, thanks again, I will try it.

I forgot to mention, another problem I ran into was that my dictionary
is a member variable of my UIViewController, I inited it in
initWithNibName, then later when I go to use it in another member
function, I found that it had been garbage-collected.  I used other
member variables the same way, but only the dictionary got
garbage-collected.  So I fixed it by doing [myDict retain]; in the
initWithNibName, but didn't understand why such a thing should be
necessary.
___

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: NSDictionary trouble

2010-01-19 Thread Jens Alfke


On Jan 19, 2010, at 10:09 AM, Paul Bruneau wrote:

When I want to find the key(s) for a given object, I use the - 
allKeysForObject method


This is fine, but keep in mind that it's a lot slower since it does a  
linear search instead of a hash lookup. (It's O(n) instead of O(1).)


If you're putting this in code you know in advance is extremely  
performance sensitive, or will operate on huge data sets; or if you  
profile it later and find this is a bottleneck; you should go to a  
reverse dictionary mapping instead.


—Jens___

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: NSDictionary trouble

2010-01-19 Thread Jens Alfke


On Jan 19, 2010, at 8:53 AM, Shawn Rutledge wrote:


I wish NSDictionary (NSMutableDictionary actually) could handle
arbitrary mappings of one type of object to another, without copying
the keys.


It can. If you have a custom class you want to be able to use as a  
dictionary key without copying, then make it implement the NSCopying  
protocol and add this method:

- (id) copyWithZone: (NSZone*)zone {
return [self retain];
}
This enables -copy but turns it into a no-op that returns the original  
object. (This is perfectly kosher. Most immutable Foundation objects  
do the same thing, i.e. copying an immutable NSString returns the same  
object.)


Of course you also have to implement -hash and -isEqual: to make your  
class play nicely with dictionaries. Make sure these have immutable  
semantics: if the values returned by these can ever change, you'll  
screw up any dictionary or set the object is in.



I didn't try CFDictionary yet; is that appropriate for an iPhone app?


Yes, you can use CF. Remember that a CFXXXRef is the same as an  
NSXXX*, you can just typecast between them. If you create a  
CFDictionary you'll have to define your own callbacks, and make the  
copy callback just retain the object.


But try NSMapTable first. It's sort of halfway between the two — it's  
an Objective-C class but it has greater flexibility in what it can  
store and how it stores it.


—Jens___

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: NSDictionary trouble

2010-01-19 Thread Paul Bruneau


On Jan 19, 2010, at 11:53 AM, Shawn Rutledge wrote:


I wish NSDictionary (NSMutableDictionary actually) could handle
arbitrary mappings of one type of object to another, without copying
the keys.  A string makes a good key most of the time but what about
the case where you want to do the reverse mapping, to find the string
which you have associated with a particular object?


When I want to find the key(s) for a given object, I use the - 
allKeysForObject method

___

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


NSDictionary trouble

2010-01-19 Thread Shawn Rutledge
I wish NSDictionary (NSMutableDictionary actually) could handle
arbitrary mappings of one type of object to another, without copying
the keys.  A string makes a good key most of the time but what about
the case where you want to do the reverse mapping, to find the string
which you have associated with a particular object?  I'm accustomed to
things like Qt and Java where hashtables can contain anything for both
key and value.  Is there an alternative which does work that way?  I
didn't try CFDictionary yet; is that appropriate for an iPhone app?
___

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