Re: Problem parsing file in 64 bit build.

2012-05-07 Thread Quincey Morris
On May 6, 2012, at 22:51 , Graham Cox wrote:

 Could this be caused by the 64 bit compiler padding out my structures in a 
 different way for 64-bit builds?

Yes, I believe in 64-bit builds 8-byte data types are 8-byte aligned, while 
they're only 4-bit aligned in 32-bit builds -- or something like that.

 If so is there a way to tell it not to for these types?

Try this:

typedef struct {
...
} __attribute__ ((packed)) MyStruct;


___

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: Problem parsing file in 64 bit build.

2012-05-07 Thread Quincey Morris
On May 6, 2012, at 23:30 , Quincey Morris wrote:

 while they're only 4-bit aligned

Er … 4-byte aligned.

Also, be careful when debugging these with lldb. At some versions of lldb get 
the member offsets and struct size wrong in packed structs, so debugger member 
display is wrong, and so is offset/size-related pointer arithmetic in debugger 
expressions.


___

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: Window snapping to main screen

2012-05-07 Thread Eric Matecki

Hello,

nobody has an idea ?

On 03/05/12 10:27, Eric Matecki wrote:

Hi everybody,

I have two screens on my MacPro (10.7.3)

When opening a window with the following code :

// create a reference rect
NSRect contentSize = NSMakeRect( iX, iY, iW, iH );

// allocate window
NSUInteger styleMask =
NSTitledWindowMask |
NSClosableWindowMask |
NSMiniaturizableWindowMask |
NSResizableWindowMask;

mWindow = [[NSWindow alloc] initWithContentRect: contentSize styleMask: 
styleMask backing: NSBackingStoreBuffered defer: YES];
Cocoa_WindowDelegate* delegate = [[Cocoa_WindowDelegate alloc] init];
[mWindow setDelegate: delegate];

// show window
[mWindow makeKeyAndOrderFront: mWindow];
[mWindow makeMainWindow];

where iX,iY,iW,iH are the wanted position and w/h of the window, the window always 
snaps to the main screen.
It's y,w,h are correct, but x is adjusted so the window either fits entirely on 
the main screen (flush at the right border), or if
it's too wide, x is set to 0. Even if the asked for position is entirely on the 
second screen and doesn't straddle the boundary
between the screens.
Other apps don't have this problem.

What am I doing wrong or what did I forget to do ?

Thanks for your help.




--
Keep intel OUTSIDE my Mac !
Hiii !!! I can see Intel chips creeping around my G5 !

Eric 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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Problem parsing file in 64 bit build.

2012-05-07 Thread Graham Cox
Thanks Quincey, it set me on the right track,

I used #pragma pack(4) for these structures (with relevant push and pops so 
it's isolated to this case only) and it all started working fine.

Is using the syntax you suggested considered better form than #pragma,?


--Graham




On 07/05/2012, at 4:30 PM, Quincey Morris wrote:

 On May 6, 2012, at 22:51 , Graham Cox wrote:
 
 Could this be caused by the 64 bit compiler padding out my structures in a 
 different way for 64-bit builds?
 
 Yes, I believe in 64-bit builds 8-byte data types are 8-byte aligned, while 
 they're only 4-bit aligned in 32-bit builds -- or something like that.
 
 If so is there a way to tell it not to for these types?
 
 Try this:
 
   typedef struct {
   ...
   } __attribute__ ((packed)) MyStruct;
 
 

___

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: Problem parsing file in 64 bit build.

2012-05-07 Thread Quincey Morris
On May 7, 2012, at 00:22 , Graham Cox wrote:

 Is using the syntax you suggested considered better form than #pragma,?

I have a vague recollection that #pragma pack was already deprecated in GCC, so 
__attribute__ ((packed)) might be the more compatible choice, but finding 
trustworthy, non-out-of-date documentation for compiler options can be a bit of 
a challenge.


___

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: Window snapping to main screen

2012-05-07 Thread Quincey Morris
On May 7, 2012, at 00:14 , Eric Matecki wrote:

 mWindow = [[NSWindow alloc] initWithContentRect: contentSize styleMask: 
 styleMask backing: NSBackingStoreBuffered defer: YES];

I would assume that the content rect is here assumed to be relative to the main 
screen. Have you tried 'initWithContentRect:styleMask:backing:defer:screen:' 
instead?


___

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: Window snapping to main screen

2012-05-07 Thread Quincey Morris
On May 7, 2012, at 00:30 , Quincey Morris wrote:

 On May 7, 2012, at 00:14 , Eric Matecki wrote:
 
 mWindow = [[NSWindow alloc] initWithContentRect: contentSize styleMask: 
 styleMask backing: NSBackingStoreBuffered defer: YES];
 
 I would assume that the content rect is here assumed to be relative to the 
 main screen. Have you tried 
 'initWithContentRect:styleMask:backing:defer:screen:' instead?

Er…having trouble saying what I mean today…

I meant to say that the content rect is assumed to be relative to the main 
screen, and windows are constrained to the boundaries of their screen. 
Presumably specifying the screen via the alternative initializer will cause it 
to constrain to that screen, and you can use a different contentRect if you 
want to position it directly.

If you want to defeat the constraining, for a specific screen, you have to 
subclass NSWindow and override 'constrainFrameRect:toScreen:' to do whatever 
you want.


___

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: Minimal document-based app

2012-05-07 Thread ecir hana
Thank you all very much, it is much clearer to me now. I'm diving into
documentation now...
___

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: Window snapping to main screen

2012-05-07 Thread Eric Matecki

On 07/05/12 09:39, Quincey Morris wrote:

On May 7, 2012, at 00:30 , Quincey Morris wrote:


On May 7, 2012, at 00:14 , Eric Matecki wrote:


mWindow = [[NSWindow alloc] initWithContentRect: contentSize styleMask: 
styleMask backing: NSBackingStoreBuffered defer: YES];


I would assume that the content rect is here assumed to be relative to the main 
screen. Have you tried
'initWithContentRect:styleMask:backing:defer:screen:' instead?


Er…having trouble saying what I mean today…

I meant to say that the content rect is assumed to be relative to the main 
screen, and windows are constrained to the boundaries
of their screen. Presumably specifying the screen via the alternative 
initializer will cause it to constrain to that screen, and
you can use a different contentRect if you want to position it directly.

If you want to defeat the constraining, for a specific screen, you have to 
subclass NSWindow and override
'constrainFrameRect:toScreen:' to do whatever you want.


Thanks Quincey, I will look at overriding constrainFrameRect:toScreen:

The content rect is relative to the main screen, that's what I want and what I 
get anyhow when calling:
[mWindow  contentRectForFrameRect: [mWindow  frame]].

So I assumed passing it back to the window initialization method will put my 
window back where it was.

--
Keep intel OUTSIDE my Mac !
Hiii !!! I can see Intel chips creeping around my G5 !

Eric 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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Problem parsing file in 64 bit build.

2012-05-07 Thread Charles Srstka
On May 7, 2012, at 2:28 AM, Quincey Morris wrote:

 On May 7, 2012, at 00:22 , Graham Cox wrote:
 
 Is using the syntax you suggested considered better form than #pragma,?
 
 I have a vague recollection that #pragma pack was already deprecated in GCC, 
 so __attribute__ ((packed)) might be the more compatible choice, but finding 
 trustworthy, non-out-of-date documentation for compiler options can be a bit 
 of a challenge.

Myself, I like to just spin off a method or function that takes a chunk of data 
and populates the fields of the struct one by one, instead of writing the data 
straight onto the struct. A little more code, but you know it’s going to work 
right without any surprises.

Charles


___

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

iOS + and X buttons

2012-05-07 Thread Alex Zavatone
I just added a blue + button to my iOS button graphics.  It's almost 100% 
accurate and should be good enough if anyone wants to reuse it. 

The edges of the + inside the blue are not as sharp as Apple's, and the + 
itself is almost pixel perfect, but I'm being a perfectionist here and can fix 
those bits later..  

Please let me know if anyone wants this to use this and I'll make more sizes 
available.  

It's here with up and down states: 

http://imgur.com/a/FPDTQ


The red X is up here:

http://imgur.com/a/gDnpx




Cheers, 
- Alex Zavatone

___

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: Problem parsing file in 64 bit build.

2012-05-07 Thread Stephen J. Butler
On Mon, May 7, 2012 at 8:06 AM, Charles Srstka cocoa...@charlessoft.com wrote:
 Myself, I like to just spin off a method or function that takes a chunk of 
 data and populates the fields of the struct one by one, instead of writing 
 the data straight onto the struct. A little more code, but you know it’s 
 going to work right without any surprises.

Not only that, but writing structs to file handles has caused security
problems before. Consider what happens if you have a short or byte
field and the compiler pads the struct. Now there's memory in your
struct that never gets initialized. If you write that to a file or
socket you're sending whatever might have been lurking there.
Passwords, login details...

___

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: My app thinks it is a phone. Why?

2012-05-07 Thread David Duncan
On May 5, 2012, at 10:15 PM, Gerriet M. Denkmann wrote:

 My app (iOS 5.1) has a xib called MainWindow.xib which does NOT contain a 
 window, just two objects, one of this is an UIApplicationDelegate.
 
 This UIApplicationDelegate has:
 
 - (void)applicationDidFinishLaunching:(UIApplication *)application 
 {
   NSLog(@%s %u,__FUNCTION__,[[UIDevice currentDevice] 
 userInterfaceIdiom]);
   ...
 }
 
 When I run this in iPad 5.1 Simulator, it prints 0 = 
 UIUserInterfaceIdiomPhone.
 
 Why does this thing delude itself being a phone? 
 
 (This was an iPhone project, which I am now trying to make universal).


Are you sure you've configured your application to target both iPhone and iPad? 
Check that the Project and Target levels match and say the same thing.
--
David Duncan


___

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: NSView + NSScrollView, not scrolling

2012-05-07 Thread qvacua
No, it does not help. I think since I am not scaling the view or sth.
like that, the difference between frame and bounds should be
irrelevant for this problem.

Tae

On Sat, May 5, 2012 at 6:12 PM, Andy Lee ag...@mac.com wrote:
 On May 5, 2012, at 3:31 AM, qvacua wrote:
 - (void)drawRect:(NSRect)dirtyRect {
    [[NSColor yellowColor] set];
    NSRectFill([self frame]);
 }

 Using [self frame] is a bug. [self frame] returns a rectangle in the 
 *superview's* coordinate system, whereas NSRectFill expects a rectangle in 
 *self's* coordinate system. Does it help if you correct this to 
 NSRectFill([self bounds])?

 --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: inconsistent behavior of NSString's localizedCaseInsensitiveCompare

2012-05-07 Thread Martin Wierschin
 If I'm right, then sort order and search order are different, and you can't 
 expect to use a binary search here. (Not unless you originally used 
 pair-wise 'localizedCaseInsensitiveCompare' to manually sort the list of 
 strings.)
 
 All comparisons, including those used for the original sorting, were done 
 using the same comparison method/locale. And the sort order and search order 
 need to be same, otherwise any algorithms that rely on the transitive nature 
 of comparisons (eg: quicksort, binary search, etc) will fail.
 
 If I understand Quincey correctly, that's exactly what he's saying: the 
 semantics of localizedCaseInsensitiveCompare: might be such that it is not 
 appropriate for such algorithms.

As Jens mentioned, that doesn't make any sense. What good is a localized 
comparison method if not for sorting a list for display? I suppose you could be 
implying that Cocoa's sorting methods aren't optimized to assume comparisons 
are transitive (or special cases problematic strings/comparisons), but that 
seems quite unlikely.

Actually, it's possible to test indirectly. I bet we could construct a set of 
strings that sorts differently depending on the input order. Ah yes:

- (void) testSorting
{
NSArray* words = [NSArray arrayWithObjects:@laso, @lassos, @las, 
@moo, @lasso, @aaa, @lassoMore, @le, @mum, nil];
NSString* problemWord = @laßt;

SEL sortSelector = @selector(localizedCaseInsensitiveCompare:);
NSArray* sorted = [[words arrayByAddingObject:problemWord] 
sortedArrayUsingSelector:sortSelector];

// words should sort consistently, no matter where the problem word is 
inserted
NSUInteger count = [words count];
for( NSUInteger insertIndex = 0; insertIndex  count; insertIndex++ ) {
NSMutableArray* testSort = [[words mutableCopy] autorelease];
[testSort insertObject:problemWord atIndex:insertIndex];
[testSort sortUsingSelector:sortSelector];

STAssertTrue( [testSort isEqual:sorted], @sorted array should 
always be the same );
}
}

That fails 5 of out the 9 loop iterations.

Well, I'm certainly very happy that Apple implements all the Unicode collation 
rules for us for various locales! But I think this must be classified as a bug.

~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: inconsistent behavior of NSString's localizedCaseInsensitiveCompare

2012-05-07 Thread Martin Wierschin
 So even if we get the right compare options, 
 'localizedCaseInsensitiveCompare:' may not be viable for strings *not* in the 
 language of the current locale.

That seems extremely unlikely and would be short-sighted of Apple, considering 
multilingual users and international information exchange.

~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: inconsistent behavior of NSString's localizedCaseInsensitiveCompare

2012-05-07 Thread Quincey Morris
On May 7, 2012, at 13:35 , Martin Wierschin wrote:

 As Jens mentioned, that doesn't make any sense. What good is a localized 
 comparison method if not for sorting a list for display? I suppose you could 
 be implying that Cocoa's sorting methods aren't optimized to assume 
 comparisons are transitive (or special cases problematic 
 strings/comparisons), but that seems quite unlikely.

You're both sliding right over the specifics of what I said:

1. You cannot reasonably use 'localizedCaseInsensitiveCompare:' *alone* to sort 
and later insert strings into a list of strings that is case insensitive in 
the sense you originally seemed to mean. Specifically, you cannot determine an 
order for *different* strings that compare *equal* using this method alone 
(e.g. a and A).

I never said nor intended to say that localized comparison methods *generally* 
are useless. Just this one, for this particular purpose. The correct method for 
this particular purpose seems to be 'compare: … options: 
NSCaseInsensitiveSearch | NSForcedOrderingSearch locale: nil'. Note that this 
is *not* a case-insensitive comparison -- a and A are *unequal* in this 
case.

Another possible alternative is 'localizedStandardCompare:', although there's 
no API contract here about what strings are equal.

This point has nothing to do with the language or character set used by the 
strings.

2. Case is a *language-dependent* concept. There's *no* answer to the question 
Are these two strings equal ignoring case? unless you know the language of 
*each* of the strings.

NSString has no comparison function that lets you specify the locale -- and 
hence language -- of each string separately. At best, the localized comparison 
methods let you specify the locale assumed for *both* strings.

This doesn't necessarily mean you can't case-insensitively sort a list of 
mixed-language strings. It does necessarily mean you can't case-insensitively 
sort a list of mixed-language strings *using NSString comparison methods only*.

The best you can do with NSString *only* is to assume that words like laßt 
are just mis-spelled English words (if your locale is us_EN). You can't then 
expect them to sort like they would in their actual language, though of course 
you can expect transitivity in the comparison methods.

3. You *did* demonstrate (and 2 other people confirmed) a case-insensitive 
transitivity failure for us_EN in 10.6.8. Markus found no transitivity failure 
for de_AT; I found no transitivity failure for us_EN in 10.7.3, though you 
reported you did; no one has reported a transitivity failure other than a 
case-insensitive comparison involving ß.

There does seem to be a bug here, but the exact set of conditions isn't clear.

Maybe give 'localizedStandardCompare:' a try?


___

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: inconsistent behavior of NSString's localizedCaseInsensitiveCompare

2012-05-07 Thread Martin Wierschin
 As Jens mentioned, that doesn't make any sense. What good is a localized 
 comparison method if not for sorting a list for display? I suppose you could 
 be implying that Cocoa's sorting methods aren't optimized to assume 
 comparisons are transitive (or special cases problematic 
 strings/comparisons), but that seems quite unlikely.
 
 You're both sliding right over the specifics of what I said:

 
 1. You cannot reasonably use 'localizedCaseInsensitiveCompare:' *alone* to 
 sort and later insert strings into a list of strings that is case 
 insensitive in the sense you originally seemed to mean.

I'm sliding over the details of what you said because they're irrelevant for my 
purposes. All I need is a consistent/transitive comparison, which I think is a 
reasonable expectation. Again, jumping straight to the point:

 The best you can do with NSString *only* is to assume that words like laßt 
 are just mis-spelled English words (if your locale is us_EN). You can't then 
 expect them to sort like they would in their actual language, though of 
 course you can expect transitivity in the comparison methods.

That's all I expect. I don't care where laßt is placed in the sort order for 
en_US (or any other locale), just that it has a single consistent location 
(so long as the same locale is always used for all comparisons).

 3. You *did* demonstrate (and 2 other people confirmed) a case-insensitive 
 transitivity failure for us_EN in 10.6.8. Markus found no transitivity 
 failure for de_AT; I found no transitivity failure for us_EN in 10.7.3, 
 though you reported you did;

That's correct- I reproduced that the comparison is not transitive for some 
strings with an eszett character on 10.6.8 and 10.7.3 with the en_US locale. 
I have since noticed that the project's base and deployment SDK are set to 
10.6, so perhaps the bug only manifests because the frameworks are providing 
compatibility.

 Maybe give 'localizedStandardCompare:' a try?

Thank you for the idea, but that won't be suitable for me because I need to be 
able to specify the locale.

Well, I'll try bumping the base SDK to 10.7. If I can still reproduce the issue 
after that, I'll file a radar.

~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

Implementing undo in custom model object for lots of properties

2012-05-07 Thread Ben Kennedy
Hi all,

I have a custom data model object with a number of properties of various basic 
types.  An array of these is managed by an NSArrayController and bound to an 
NSTableView (as the reader might recall from my earlier thread).  I am not 
using Core Data.

I am now wiring in undo support.  Were the data backed by an 
NSManagedObjectContext, I would get undo behaviour for free, but since there 
isn't, I need to write my own setters to handle it.

It seems onerous, verbose and error-prone to have to implement a custom stub 
setter method for every property like so:

- (void)setBlah:(Blah *)newBlah
{
if (newBlah != blah)
{
[undoManager registerUndoWithTarget:self 
selector:@selector(setBlah:) object:blah];
[blah release];
blah = [newBlah copy];
}
}

Thus, I have tried to be clever by doing the following override:

- (void)setValue:(id)value forKey:(NSString *)key
{
NSArray *undoableKeys = [NSArray arrayWithObjects: @blah, @foo, 
@anotherProperty, nil];

if ([undoableKeys containsObject:key])
{
[[undoManager prepareWithInvocationTarget:self] setValue:[self 
valueForKey:key] forKey:key];
}

[super setValue:value forKey:key];

return;
}

However, the undo event does not seem to be recorded -- the Undo menu command 
remains ghosted.  It is not clear to me why.

It wouldn't surprise me to be admonished for such an abuse of setValue:forKey:, 
but is there a better way?  I imagine this idiom must be extremely commonplace, 
but I could not find a clear directive.

I looked to Apple's DemoMonkey sample for its undo practices, and it just 
implements the verbose boilerplate for each property.  Is that really the 
recommended solution?

thanks,

-ben

--
Ben Kennedy, chief magician
Zygoat Creative Technical Services
http://www.zygoat.ca


___

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: Problem parsing file in 64 bit build.

2012-05-07 Thread Graham Cox
Understood, but in this case I'm not writing anything. I'm reading a file into 
a NSData, and using these structs to put a frame onto the data in places so I 
can extract data from the fields.

The alternative would be to pull out each data field one by one, which I'm sure 
is also considered acceptable practice, but for this file type, using structs 
has proved to be a lot easier, not least because of a) the strange mix of 
big-endian and little-endian values in the same file and b) the presence of 
directly formatted 'double' values that are not platform independent.

Some discussion of the merit of #pragma pack(n) versus other methods would be 
useful here, it's not something I've had to deal with very much.

--Graham




On 08/05/2012, at 3:43 AM, Stephen J. Butler wrote:

 On Mon, May 7, 2012 at 8:06 AM, Charles Srstka cocoa...@charlessoft.com 
 wrote:
 Myself, I like to just spin off a method or function that takes a chunk of 
 data and populates the fields of the struct one by one, instead of writing 
 the data straight onto the struct. A little more code, but you know it’s 
 going to work right without any surprises.
 
 Not only that, but writing structs to file handles has caused security
 problems before. Consider what happens if you have a short or byte
 field and the compiler pads the struct. Now there's memory in your
 struct that never gets initialized. If you write that to a file or
 socket you're sending whatever might have been lurking there.
 Passwords, login details...


___

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: inconsistent behavior of NSString's localizedCaseInsensitiveCompare

2012-05-07 Thread Quincey Morris
On May 7, 2012, at 16:07 , Martin Wierschin wrote:

 I'm sliding over the details of what you said because they're irrelevant for 
 my purposes.


OK, but I'd *really* appreciate it if you'd avoid calling my replies senseless:

 On May 7, 2012, at 13:35 , Martin Wierschin wrote:
 
 As Jens mentioned, that doesn't make any sense.

On May 7, 2012, at 16:07 , Martin Wierschin wrote:

 Maybe give 'localizedStandardCompare:' a try?
 
 Thank you for the idea, but that won't be suitable for me because I need to 
 be able to specify the locale.

And you were going to specify the locale for 'localizedCaseInsensitiveCompare:' 
how?


___

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: Implementing undo in custom model object for lots of properties

2012-05-07 Thread Graham Cox
Hi Ben,

I think this undo approach should work fine.

Another way to 'centralise' undo is to have an object listen for the KVO 
notifications of changes for properties it's interested in, and use the 
observation method to record to the undo manager. You'd still use 
setValue:forKey: at undo time, so it amounts to a very similar idea. I've done 
it that way and it works.

So your problem must be something else. Are you sure undoManager returns 
something?

Also, more obvious now I come to think about it, is that setValue:forKey: is 
not called for every property when it is set! That method can be used to call 
down to the setter for a named property, but if the setter is invoked directly 
(the more usual case), then setValue:forKey: isn't invoked. You might want to 
check whether that is what's happening. In which case making your undo handler 
a KVO observer will get around that problem, or you could override 
-willChangeValueForKey: instead, which is the method that causes some of the 
KVO magic to happen.

--Graham



On 08/05/2012, at 9:11 AM, Ben Kennedy wrote:

 I have a custom data model object with a number of properties of various 
 basic types.  An array of these is managed by an NSArrayController and bound 
 to an NSTableView (as the reader might recall from my earlier thread).  I am 
 not using Core Data.
 
 I am now wiring in undo support.  Were the data backed by an 
 NSManagedObjectContext, I would get undo behaviour for free, but since there 
 isn't, I need to write my own setters to handle it.
 
 It seems onerous, verbose and error-prone to have to implement a custom stub 
 setter method for every property like so:
 
 - (void)setBlah:(Blah *)newBlah
   {
   if (newBlah != blah)
   {
   [undoManager registerUndoWithTarget:self 
 selector:@selector(setBlah:) object:blah];
   [blah release];
   blah = [newBlah copy];
   }
   }
 
 Thus, I have tried to be clever by doing the following override:
 
 - (void)setValue:(id)value forKey:(NSString *)key
   {
   NSArray *undoableKeys = [NSArray arrayWithObjects: @blah, @foo, 
 @anotherProperty, nil];
   
   if ([undoableKeys containsObject:key])
   {
   [[undoManager prepareWithInvocationTarget:self] setValue:[self 
 valueForKey:key] forKey:key];
   }
   
   [super setValue:value forKey:key];
   
   return;
   }
 
 However, the undo event does not seem to be recorded -- the Undo menu command 
 remains ghosted.  It is not clear to me why.
 
 It wouldn't surprise me to be admonished for such an abuse of 
 setValue:forKey:, but is there a better way?  I imagine this idiom must be 
 extremely commonplace, but I could not find a clear directive.
 
 I looked to Apple's DemoMonkey sample for its undo practices, and it just 
 implements the verbose boilerplate for each property.  Is that really the 
 recommended solution?

___

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: Problem parsing file in 64 bit build.

2012-05-07 Thread Jens Alfke

On May 7, 2012, at 4:35 PM, Graham Cox wrote:

 The alternative would be to pull out each data field one by one, which I'm 
 sure is also considered acceptable practice, but for this file type, using 
 structs has proved to be a lot easier, not least because of a) the strange 
 mix of big-endian and little-endian values in the same file and b) the 
 presence of directly formatted 'double' values that are not platform 
 independent.

I agree; using structs for this results in the cleanest code.

 Some discussion of the merit of #pragma pack(n) versus other methods would be 
 useful here, it's not something I've had to deal with very much.

Assuming this just needs to support Mac and/or iOS, go ahead and use #pragma 
pack. If your code really has to be fully cross-platform, then things get 
dicier because #pragma pack isn’t supported by all compilers.

—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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: inconsistent behavior of NSString's localizedCaseInsensitiveCompare

2012-05-07 Thread Martin Wierschin
 I'm sliding over the details of what you said because they're irrelevant for 
 my purposes.
 
 OK, but I'd *really* appreciate it if you'd avoid calling my replies 
 senseless:

I never said your replies are senseless. The sequence was:

 On 2012.05.05, at 4:51 PM, Kyle Sluder wrote:
 If I understand Quincey correctly, that's exactly what he's saying: the 
 semantics of localizedCaseInsensitiveCompare: might be such that it is not 
 appropriate for such algorithms.
 
 On 2012.05.07, at 1:35 PM, Martin Wierschin wrote:
 As Jens mentioned, that doesn't make any sense.

My quick dismissal that it doesn't any sense was about Kyle's suggestion that 
perhaps localizedCaseInsensitiveCompare isn't suitable for algorithms which 
require a transitive comparison operation.

Anyways, I certainly didn't mean to offend you- if I did, I apologize.


 Maybe give 'localizedStandardCompare:' a try?
 
 Thank you for the idea, but that won't be suitable for me because I need to 
 be able to specify the locale.
 
 And you were going to specify the locale for 
 'localizedCaseInsensitiveCompare:' how?

I'm not actually using that method, it's just a nice compact name for the 
mailing list, and has the same errant behavior as -[NSString 
compare:options:range:locale:] and CFStringCompareWithOptionsAndLocale.

~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: My app thinks it is a phone. Why?

2012-05-07 Thread Gerriet M. Denkmann

On 8 May 2012, at 01:08, David Duncan wrote:

 On May 5, 2012, at 10:15 PM, Gerriet M. Denkmann wrote:
 
 My app (iOS 5.1) has a xib called MainWindow.xib which does NOT contain a 
 window, just two objects, one of this is an UIApplicationDelegate.
 
 This UIApplicationDelegate has:
 
 - (void)applicationDidFinishLaunching:(UIApplication *)application 
 {
  NSLog(@%s %u,__FUNCTION__,[[UIDevice currentDevice] 
 userInterfaceIdiom]);
  ...
 }
 
 When I run this in iPad 5.1 Simulator, it prints 0 = 
 UIUserInterfaceIdiomPhone.
 
 Why does this thing delude itself being a phone? 
 
 (This was an iPhone project, which I am now trying to make universal).
 
 
 Are you sure you've configured your application to target both iPhone and 
 iPad? Check that the Project and Target levels match and say the same thing.

You are absolutely right: it turned out to be wrong settings:

1. Target → Info → Application requires iPhone environment was YES
2. Bild Settings → Deployment → Targeted Device Family was just iPhone

The first one I found early, the second one many hours after asking the list.

I think this is a general Xcode problem: starting with the right template 
everything is very smooth.
But changing directions later (like iPhone only to universal, or 
non-document-based to document-based) is kind of difficult - there are so many 
settings which may or may not be relevant.

It would be rather nice if Xcode allowed me formulate a wish (like This 
project should be universal) and it answered with a list of things which must 
be (or probably should be) done:
Like: Targeted Device Family must be changed to iPhone/iPad and some buttons: 
Show me and: Please do it for me.
Followed by: Read more about this in the xxx-Guide with a helpful button: 
Open in Browser.

Such a list probably cannot be exhaustive (even if following all suggestions, 
some problems might remain) but it would very helpful indeed.


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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

monitoring changes in a local property

2012-05-07 Thread Koen van der Drift
One of my viewcontrollers uses the representedObject to bind to the 
NSArrayController that holds all the data for the application (OS X, ARC on). I 
declared a local property mySelection (an NSArray) and bind it to the 
representedObject as follows:

[self bind:@mySelection toObject:self.representedObject 
withKeyPath:@selectedObjects options:nil];

So far so good.

Now when the user changes mySelection,  not only my local property needs to be 
updated, but also some other parts in my code. So I cannot just rely on the 
automatically generated setter, and thus need to monitor a change in 
mySelection.  After some searching I came up with the following:

[self.representedObject addObserver:self forKeyPath:@selectedObjects  
options:NSKeyValueObservingOptionNew context: nil];
 
and then:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString: @selectedObjects])
{
   // do additional stuff
}
else 
{
[super observeValueForKeyPath:keyPath ofObject:object change:change 
context:context];
}
}

Again, this all works. Whenever the user changes the selection, 
observeValueForKeyPath: gets called and the do additional stuff gets executed.

But I have the feeling I am over-complicating things.  From reading on this 
subject I get the impression the approach above seems to be more for monitoring 
properties in other classes, not in the owner class.

So, is this the correct way to do this (responding to a change in a local 
property, or am I overlooking something very obvious?

Thanks,

- Koen.
___

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: Implementing undo in custom model object for lots of properties

2012-05-07 Thread Ben Kennedy
On 07 May 2012, at 4:45 pm, Graham Cox wrote:

 Another way to 'centralise' undo is to have an object listen for the KVO 
 notifications of changes for properties it's interested in, and use the 
 observation method to record to the undo manager. You'd still use 
 setValue:forKey: at undo time, so it amounts to a very similar idea. I've 
 done it that way and it works.

Well, that would require my controller to -addObserver:... on each of the 
collected objects, which I had earlier decided to avoid for various reasons.  
But that's a good technique for me to keep in mind, and is beginning to sound 
like possibly a better approach.

 So your problem must be something else. Are you sure undoManager returns 
 something?

You're right, I deked myself out; I was trying to examine changes to a property 
that was changed via the setter of a different property, but setValue:forKey: 
was not being called for the former.  I wasn't looking closely enough at the 
call stack or the forKey: parameter when I saw the seemingly do-nothing 
undoManager line dutifully execute.

But, that's sort of moot because as you point out...:

 Also, more obvious now I come to think about it, is that setValue:forKey: is 
 not called for every property when it is set! That method can be used to call 
 down to the setter for a named property, but if the setter is invoked 
 directly (the more usual case), then setValue:forKey: isn't invoked. You 
 might want to check whether that is what's happening. In which case making 
 your undo handler a KVO observer will get around that problem, or you could 
 override -willChangeValueForKey: instead, which is the method that causes 
 some of the KVO magic to happen.

Much better idea, thanks.  Moving my undo registration shim into 
-willChangeValueForKey: solves the problem nicely:

- (void)willChangeValueForKey:(NSString *)key
{
// Register the inverse action if we are about to change an undoable 
property.
if ([[FAEditorNote undoableKeys] containsObject:key])
[[undoManager prepareWithInvocationTarget:self] setValue:[self 
valueForKey:key] forKey:key];

[super willChangeValueForKey:key];

return;
}

Which allows me to turf this gnarly macro I briefly purpose-built in the 
interim:

#define DEFINE_UNDOABLE_COPYING_SETTER(SETTER,PROPERTY) \
- (void)SETTER(id)newValue \
{ \
if (newValue != PROPERTY) \
{ \
[undoManager registerUndoWithTarget:self 
selector:@selector(SETTER) object:PROPERTY]; \
[PROPERTY release]; \
PROPERTY = [newValue copy]; \
} \
}

DEFINE_UNDOABLE_COPYING_SETTER(setPgmInTC:, pgmInTC);
DEFINE_UNDOABLE_COPYING_SETTER(setPgmOutTC:, pgmOutTC);
//etc.

thanks!

b

--
Ben Kennedy, chief magician
Zygoat Creative Technical Services
http://www.zygoat.ca


___

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: monitoring changes in a local property

2012-05-07 Thread Roland King
It's ok, you can do it if you like, monitor your own properties, however if all 
you really want to do here is, in your own class, do something more when 
mySelection is changed, you can write your own setter and put it in there 
yourself directly. 

-(void)setMySelection:(NSArray*)mySelection
{
// set whatever instance variable you have for mySelection, with 
appropriate memory management if necessary

// do the other stuff you want to do
}

you'll have to write the getter as well, you can't write one and synthesize the 
other any more. 

One more point, never, ever use addObserver:forKeyPath:options:context with a 
nil context. It's so tempting, it's such an easy habit to get into, it will get 
you one day and the resulting bug will make you tear your hair out for days. 
Set up a static for the context, use it, CHECK the context in the 
observeValueForKeyPath:.. call and only process if the context is yours else 
call super. Also, as Apple has now finally kindly allowed us to specify the 
context when we remove observers instead of the runtime guessing and getting it 
wrong, always use that version. 

On May 8, 2012, at 11:16 AM, Koen van der Drift wrote:

 One of my viewcontrollers uses the representedObject to bind to the 
 NSArrayController that holds all the data for the application (OS X, ARC on). 
 I declared a local property mySelection (an NSArray) and bind it to the 
 representedObject as follows:
 
[self bind:@mySelection toObject:self.representedObject 
 withKeyPath:@selectedObjects options:nil];
 
 So far so good.
 
 Now when the user changes mySelection,  not only my local property needs to 
 be updated, but also some other parts in my code. So I cannot just rely on 
 the automatically generated setter, and thus need to monitor a change in 
 mySelection.  After some searching I came up with the following:
 
[self.representedObject addObserver:self forKeyPath:@selectedObjects  
 options:NSKeyValueObservingOptionNew context: nil];
 
 and then:
 
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
 change:(NSDictionary *)change context:(void *)context
 {
if ([keyPath isEqualToString: @selectedObjects])
{
   // do additional stuff
}
else 
{
[super observeValueForKeyPath:keyPath ofObject:object change:change 
 context:context];
}
 }
 
 Again, this all works. Whenever the user changes the selection, 
 observeValueForKeyPath: gets called and the do additional stuff gets 
 executed.
 
 But I have the feeling I am over-complicating things.  From reading on this 
 subject I get the impression the approach above seems to be more for 
 monitoring properties in other classes, not in the owner class.
 
 So, is this the correct way to do this (responding to a change in a local 
 property, or am I overlooking something very obvious?
 
 Thanks,
 
 - Koen.
 ___
 
 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/rols%40rols.org
 
 This email sent to r...@rols.org


___

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: monitoring changes in a local property

2012-05-07 Thread Koen van der Drift

On May 7, 2012, at 11:28 PM, Roland King wrote:

 -(void)setMySelection:(NSArray*)newSelection
 {
   // set whatever instance variable you have for mySelection, 
 with appropriate memory management if necessary


I thought about that too, but how do I do that when using ARC? Can I still do 
this:

[mySelection release];
[mySelection = [newSelection copy]];

or something along those lines?

- Koen.
___

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: monitoring changes in a local property

2012-05-07 Thread Roland King
mySelection = [ newSelection copy ];

is all you need. 

On May 8, 2012, at 11:38 AM, Koen van der Drift wrote:

 
 On May 7, 2012, at 11:28 PM, Roland King wrote:
 
 -(void)setMySelection:(NSArray*)newSelection
 {
  // set whatever instance variable you have for mySelection, 
 with appropriate memory management if necessary
 
 
 I thought about that too, but how do I do that when using ARC? Can I still do 
 this:
 
 [mySelection release];
 [mySelection = [newSelection copy]];
 
 or something along those lines?
 
 - Koen.


___

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: monitoring changes in a local property

2012-05-07 Thread Eeyore
Roland's right about ARC, you just need the set and copy. Just for the record, 
I don't think the pattern you present is safe when newSelection equals 
mySelection (as you release before you copy), you need something like one of 
the following:

if (mySelection != newSelection)
{
[mySelection release];
mySelection = [newSelection copy];
}

OR

[mySelection autorelease];
mySelection = [newSelection copy];

OR

oldSelection = mySelection;
mySelection = [newSelection copy];
[oldSelection release];

Aaron

On May 7, 2012, at 8:38 PM, Koen van der Drift wrote:

 
 On May 7, 2012, at 11:28 PM, Roland King wrote:
 
 -(void)setMySelection:(NSArray*)newSelection
 {
  // set whatever instance variable you have for mySelection, 
 with appropriate memory management if necessary
 
 
 I thought about that too, but how do I do that when using ARC? Can I still do 
 this:
 
 [mySelection release];
 [mySelection = [newSelection copy]];
 
 or something along those lines?
 
 - Koen.
 ___
 
 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/eeyore%40monsterworks.com
 
 This email sent to eey...@monsterworks.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: monitoring changes in a local property

2012-05-07 Thread Quincey Morris
On May 7, 2012, at 20:16 , Koen van der Drift wrote:

 One of my viewcontrollers uses the representedObject to bind to the 
 NSArrayController that holds all the data for the application (OS X, ARC on). 
 I declared a local property mySelection (an NSArray) and bind it to the 
 representedObject as follows:
 
[self bind:@mySelection toObject:self.representedObject 
 withKeyPath:@selectedObjects options:nil];
 
 So far so good.
 
 Now when the user changes mySelection,  not only my local property needs to 
 be updated, but also some other parts in my code. So I cannot just rely on 
 the automatically generated setter, and thus need to monitor a change in 
 mySelection.  After some searching I came up with the following:
 
[self.representedObject addObserver:self forKeyPath:@selectedObjects  
 options:NSKeyValueObservingOptionNew context: nil];
 
 and then:
 
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
 change:(NSDictionary *)change context:(void *)context
 {
if ([keyPath isEqualToString: @selectedObjects])
{
   // do additional stuff
}
else 
{
[super observeValueForKeyPath:keyPath ofObject:object change:change 
 context:context];
}
 }
 
 Again, this all works. Whenever the user changes the selection, 
 observeValueForKeyPath: gets called and the do additional stuff gets 
 executed.
 
 But I have the feeling I am over-complicating things.  From reading on this 
 subject I get the impression the approach above seems to be more for 
 monitoring properties in other classes, not in the owner class.
 
 So, is this the correct way to do this (responding to a change in a local 
 property, or am I overlooking something very obvious?


It's not obvious why you need a mySelection property at all. You just want to 
do additional stuff when the selection changes, so:

[self.representedObject addObserver:self forKeyPath:@selectedObjects 
options:NSKeyValueObservingOptionInitial context: myContext];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary *)change context:(void *)context
{
if (content != myContext)
[super observeValueForKeyPath:keyPath ofObject:object 
change:change context:context];
else if ([keyPath isEqualToString: @selectedObjects])
{
// do additional stuff
}
}

Note that NSKeyValueObservingOptionNew is not a useful option here, and you 
probably need NSKeyValueObservingOptionInitial to get additional stuff for 
the initial selection (which may be nil, of course, but don't assume it). Also, 
I added the missing context.

Inside the view controller, if you need the actual selection, it's 
'[[self.representedObject] selectedObjects]'. It may be convenient to package 
this into a *readonly* property:

- (NSArray*) mySelection 
{
return [[self.representedObject] selectedObjects];
}

If you actually need KVO compliance for mySelection (that is, something else 
observes *it*), then add this:

+ (NSSet*) keyPathsForValuesAffectingMySelection 
{
return [NSSet setWithObject: @representedObject.selectedObjects];
}

Don't make mySelection readwrite -- it's really a derived property and so 
should be readonly. Also, get rid of the bind invocation. It was never the 
right approach.

P.S. Personally, I wouldn't bind to a NSArrayController like this, because it 
just obscures the MVC lines of your app. The array controller is getting its 
content from somewhere: from this view controller itself, from a window 
controller, or from the app delegate. Assuming the last of these (based on your 
description of the data as app-wide), then I'd give the app delegate a 
selectionIndexes property (of type NSIndexSet*), bind the array controller's 
selectionIndexes binding to this property in IB, and have the view controller 
observe the app delegate selectionIndexes property instead of the array 
controller selectedObjects property.

The rationale for this is that the array controller is merely a glue object 
foisted on you by the bindings UI conventions, and the less your code needs to 
know about it the better.

___

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: Implementing undo in custom model object for lots of properties

2012-05-07 Thread Graham Cox

On 08/05/2012, at 1:17 PM, Ben Kennedy wrote:

 Well, that would require my controller to -addObserver:... on each of the 
 collected objects, which I had earlier decided to avoid for various reasons.  
 But that's a good technique for me to keep in mind, and is beginning to sound 
 like possibly a better approach.


Indeed, but if you are willing to have your object publish a list of keys it 
wants to be undoable (as you already are), then you can iterate over them and 
do -addObserver: in a loop, so it might not be all that bad.

However, I think that the override to -willChangeValueForkey: is just as good.

--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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com