NSNotificationCenter selector arguments - arguments

I want to call not just methods from NSNotification but the method's arguments
Something along the lines of
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerinCombat:YES) name:#"PlayerinCombat" object:nil];
and not just
#selector(playerinCombat:)
just to use with
+ (BOOL)playerinCombat:(BOOL)flag {return flag; if (flag){NSLog(#"Player in Combat.");} if (!flag){NSLog(#"Player not in Combat.");}}
But it won't work. Any ideas?

On second thought userInfo can be used (I think)

Related

can't set both name and object arguments of addObserver method

use this code
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textChanged:) name:NSTextDidChangeNotification object:self.text3];
I can not get the notification I wanted.
But if I change the name or object to nil, it works. I wonder whether these two arguments can not be set non-nil simultaneously?

Is it possible to "get" the h file when you're writing code in the m file

I'm trying to make a plugin, and the idea is that after you write something like
-(void)thisMethodIsSomethingIWantToBeExposed
Then I can press a keycombo like alt+c and then it'll write what is one the current line in the .h file so I don't have to copy paste it over myself.
Anyone have any idea on how to get the path of the file I'm currently writing in? Then I can just change the m to an h, and then I'll just have to figure out how to write to the h file, but that's another thing.
I found a solution, but I think it might be a bit hacky.
In my xcode plugin i put this in my init
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationListener:) name:nil object:nil];
And I made a method called
-(void)notificationListener:(NSNotification *)notification{
if (![notification.name isKindOfClass:[NSString class]]) {
if ([[notification name] isEqualToString:#"IDESourceCodeDocumentDidUpdateSourceModelNotification"] ) {
NSString *path = [ NSString stringWithFormat :#"%#",notification.object ];
path = [path substringFromIndex:49];
}
You'll get ALOT of notifications, and it took me a while to find one with information on the path, but this one has it.
Same method with
NSLog(#"Not recv: %#", notification.name);
will write out all the names of all the Notifications.

Find out when QTMovieView has finished playing

I have a QTMovieView, how will I be able to call a method when the movie has finished playing?
I just ended up using:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(method:) name:#"QTMovieDidEndNotification" object:nil ];

NSPrintInfo printSettings not KVO compliant despite comment saying so in the header

the background: I'm adding a print panel accessory view to a print dialog (using addAccessoryController:), with controls binded to NSPrintInfo printSettings values so the values are saved in the print presets. I'm having troubles observing printSettings changes. I'm building with SDK 10.6, testing on OS X 10.7.
Here is a code sample that should work in my understanding, but observeValueForKeyPath: is never called:
- (void)testKVO
{
NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
[printInfo addObserver:self forKeyPath:#"printSettings.foo" options:0 context:NULL];
[printInfo setValue:#"bar" forKeyPath:#"printSettings.foo"]; // observeValueForKeyPath:ofObject:change:context: not called
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(#"%s %# :: %#", _cmd, keyPath, object);
}
I also tried observing printSettings directly, with no more success, the observer method is not called either (the printSettings returned by NSPrintInfo is in fact of class NSPrintInfoDictionaryProxy):
- (void)testKVO
{
NSMutableDictionary *printSettings = [[NSPrintInfo sharedPrintInfo] printSettings];
[printSettings addObserver:self forKeyPath:#"foo" options:0 context:NULL];
[printSettings setValue:#"bar" forKey:#"foo"]; // observeValueForKeyPath:ofObject:change:context: not called
}
I double checked that my KVO system works in normal conditions and calls the observer method:
- (void)testKVO
{
NSMutableDictionary *printSettings = [NSMutableDictionary dictionary];
[printSettings addObserver:self forKeyPath:#"foo" options:0 context:NULL];
[printSettings setValue:#"bar" forKey:#"foo"]; // observeValueForKeyPath:ofObject:change:context: called at last!
}
So the question is: how can I observe printSettings modifications, especially to know when the user has chosen a print preset?
I'd also like the preview to be updated automatically with
- (NSSet *)keyPathsForValuesAffectingPreview
{
return [NSSet setWithObjects:
#"representedObject.printSettings.foo",
nil];
}
there is an easy workaround for the preview update: adding an indirection level by redeclaring the properties directly on the NSViewController itself. But for the print preset change I have no clue.
In the end, here is the comment in NSPrintInfo.h:
- (NSMutableDictionary *)printSettings;
The print info's print settings. You can put values in this dictionary to store them in any preset that the user creates while editing this print info with a print panel. Such values must be property list objects. This class is key-value coding (KVC) and key-value observing (KVO) compliant for "printSettings" so you can often bind controls in print panel accessory views directly to entries in this dictionary. You can also use this dictionary to get values that have been set by other parts of the printing system, like a printer driver's print dialog extension (the same sort of values that are returned by the Carbon Printing Manager's PMPrintSettingsGetValue() function). Other parts of the printing system often use key strings like "com.apple.print.PrintSettings.PMColorSyncProfileID" but dots like those in key strings wouldn't work well with KVC, so those dots are replaced with underscores in keys that appear in this dictionary, as in "com_apple_print_PrintSettings_PMColorSyncProfileID". You should use the same convention when adding entries to this dictionary.
Any help appreciated
Thanks
Well I found a way. There is an undocumented notification that is being sent when selecting a print preset or changing paper format, all that you have to do is add an observer:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(printInfoDidChange:) name:#"NSPrintInfoDidChange" object:nil];
That is not as straightforward as binding to printSettings keypaths, and I really don't like using an undocumented notification (almost as bad as using private API in term of maintainability) but that's the only way I could figure out to do the job.

Is there a nice way to set up KVO on retained properties?

Quite often I encounter a scenario when I want to observe changes on a retained property:
#interface AnObserver {…}
#property(retain) Foo *foo;
Now when I want to set up the observing, I need to write my own setter, repeating all the boilerplate setter code:
- (void) setFoo: (Foo*) newFoo {
if (newFoo == foo)
return;
[foo removeObserver:self forKeyPath:…];
[foo release], foo = [newFoo retain];
[foo addObserver:self forKeyPath:…];
}
This is dumb, because it pollutes the source with boilerplate code and it’s easy to miss something. Is there a better way to set up KVO on retained properties? I wish I could write something like Moose’s after hook to change the KVO after the property was changed.
In fact I realized I could watch the property itself:
[self addObserver:self forKeyPath:#"foo"…];
And then change the KVO when the property changes :-), but I do realize this is much more complicated than the hand-written setter I’d like to avoid.
Ideas?
How about using a key path? Say you want to observe changes on both the value1 and value2 properties of foo. You could use:
[self addObserver:self forKeyPath:#"foo.value1"];
[self addObserver:self forKeyPath:#"foo.value2"];
Then when those properties change, you'll get notifications.

Resources