NSNotificationCenter observers, selectors and notifications
Hi peoples, I'm not sure if I'm doing something wrong here, or if it's a bug. I'm trying to get a notification when a quicktime track finishes playing. The documentation for NSNotificationCenter says: notificationSelector Selector that specifies the message the receiver sends notificationObserver to notify it of the notification posting. The method the selector specifies must have one and only one argument (an instance of NSNotification). yet, if I use a selector that takes one argument, there is an error when the NSNotificationCenter tries to notify me: 2010-04-24 12:06:49.587 macruby[5042:903] -[Player track_finished_with_notifier]: unrecognized selector sent to instance 0x2002c3d40 On the other hand, if I give a selector that doesn't take any arguments at all, it is in fact called by the NSNotificationCenter at the right moment. I've included a quickly hacked up script that shows the problem at the end of this message. I'm using macruby 0.5 on Snow Leopard, so maybe the bug (if it is indeed a bug, and not an error on my part) is already fixed... To run the script you'll have to replace Evanescence and Going Under with a group/track that you have in your iTunes library... Alli #!/usr/local/bin/macruby require 'rubygems' require 'hotcocoa' framework 'Cocoa' framework 'QtKit' include HotCocoa class Player def init NSNotificationCenter.defaultCenter.addObserver(self, selector: :track_finished, name:QTMovieDidEndNotification, object:nil) NSNotificationCenter.defaultCenter.addObserver(self, selector: :track_finished_with_notifier, name:QTMovieDidEndNotification, object:nil) movie = getQtMovieFromArtist('Evanescence', track:'Going Under') movie.volume = 30 movie.play puts "playing..." sleep(10) self end def getQtMovieFromArtist( artist, track:track_name) iTunesXMLPath = "#{NSHomeDirectory()}/Music/iTunes/iTunes Music Library.xml" iTunesData = NSDictionary.alloc.initWithContentsOfFile(iTunesXMLPath) tracks = iTunesData.objectForKey('Tracks') artist_db = tracks.find_all { |track| track[1]['Artist'] == artist} track_db = artist_db.find{|track| track[1]['Name'] == track_name} url = NSURL.URLWithString(track_db[1]['Location']) errorptr = Pointer.new_with_type('@') movie = QTMovie.movieWithURL(url, error:errorptr) if (!movie) error = errorptr[0] puts "Error loading song: #{track_db[1]['Name']} #{error.code} #{error.localizedDescription}" end movie end def track_finished NSLog( "track finished!") end def track_finished_with_notifier(notifier) NSLog("track finished with notifier #{notifier}") end end class Application def start application :name => "Player" do |app| app.delegate = self Player.new end end def on_new(sender) Player.new end def on_close(sender) w = NSApp.mainWindow if w w.performClose self else NSBeep() end end def on_clear(sender) w = NSApp.mainWindow if w and w.respond_to?(:terminal) w.terminal.clear else NSBeep() end end end Application.new.start
Hi, In ObjC, a method 'foo' that has one argument is referenced as 'foo:' in such situations (with colon), not 'foo'. Try passing a string "track_finished_with_notifier:" to the notification center. Jakub Suder
I concur. The problem is that you call: NSNotificationCenter.defaultCenter.addObserver(self, selector: :track_finished, name:QTMovieDidEndNotification, object:nil) That means you tell the notification center to call "track_finished", not "track_finished:" :-) -- Thibault Martin-Lagardette On Apr 24, 2010, at 03:41, Jakub Suder wrote:
Hi,
In ObjC, a method 'foo' that has one argument is referenced as 'foo:' in such situations (with colon), not 'foo'. Try passing a string "track_finished_with_notifier:" to the notification center.
Jakub Suder _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
Also, note that you can use a symbol too, which is more efficient (they are only created once):
NSNotificationCenter.defaultCenter.addObserver(self, selector: :"track_finished:" name:QTMovieDidEndNotification, object:nil)
Laurent On Apr 24, 2010, at 1:32 PM, Thibault Martin-Lagardette wrote:
I concur.
The problem is that you call: NSNotificationCenter.defaultCenter.addObserver(self, selector: :track_finished, name:QTMovieDidEndNotification, object:nil)
That means you tell the notification center to call "track_finished", not "track_finished:" :-)
-- Thibault Martin-Lagardette
On Apr 24, 2010, at 03:41, Jakub Suder wrote:
Hi,
In ObjC, a method 'foo' that has one argument is referenced as 'foo:' in such situations (with colon), not 'foo'. Try passing a string "track_finished_with_notifier:" to the notification center.
Jakub Suder _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
participants (4)
-
Allison Newman
-
Jakub Suder
-
Laurent Sansonetti
-
Thibault Martin-Lagardette