[MacRuby-devel] [MacRuby] #484: scoping issues with notification center
MacRuby
ruby-noreply at macosforge.org
Fri Dec 4 23:24:50 PST 2009
#484: scoping issues with notification center
-------------------------------------+--------------------------------------
Reporter: mattaimonetti@… | Owner: lsansonetti@…
Type: defect | Status: closed
Priority: blocker | Milestone:
Component: MacRuby | Resolution: invalid
Keywords: |
-------------------------------------+--------------------------------------
Changes (by lsansonetti@…):
* status: new => closed
* resolution: => invalid
* milestone: MacRuby 0.5 =>
Old description:
> Here is a reduction of a bug I encountered today:
>
> {{{
> framework 'Cocoa'
>
> class Foo
>
> def dataReady(notification)
> puts "called ok"
> NSApplication.sharedApplication.terminate(nil)
> end
> end
>
> nc = NSNotificationCenter.defaultCenter
>
> # foo = nil
>
> Proc.new do
>
> foo = Foo.new
> task = NSTask.alloc.init
> pi = NSPipe.alloc.init
> po = NSPipe.alloc.init
>
> task.arguments = []
> task.currentDirectoryPath = "/bin/"
> task.launchPath = "/bin/ls"
> task.standardInput = pi
> task.standardOutput = po
> task.launch
>
> file_handle = po.fileHandleForReading
> file_handle.readInBackgroundAndNotify
>
> nc.addObserver(foo, selector: "dataReady:", name:
> NSFileHandleReadCompletionNotification, object: file_handle)
>
> end.call
>
> app = NSApplication.sharedApplication
> app.delegate = self
> app.run
> }}}
>
> If you run the code as is, the observer never gets called, however if you
> uncomment the line defining foo before the block everything works fine.
>
> It looks like foo isn't available when the notification center tries to
> call it to send it the notification.
New description:
Here is a reduction of a bug I encountered today:
{{{
framework 'Cocoa'
class Foo
def dataReady(notification)
puts "called ok"
NSApplication.sharedApplication.terminate(nil)
end
end
nc = NSNotificationCenter.defaultCenter
# foo = nil
Proc.new do
foo = Foo.new
task = NSTask.alloc.init
pi = NSPipe.alloc.init
po = NSPipe.alloc.init
task.arguments = []
task.currentDirectoryPath = "/bin/"
task.launchPath = "/bin/ls"
task.standardInput = pi
task.standardOutput = po
task.launch
file_handle = po.fileHandleForReading
file_handle.readInBackgroundAndNotify
nc.addObserver(foo, selector: "dataReady:", name:
NSFileHandleReadCompletionNotification, object: file_handle)
end.call
app = NSApplication.sharedApplication
app.delegate = self
app.run
}}}
If you run the code as is, the observer never gets called, however if you
uncomment the line defining foo before the block everything works fine.
It looks like foo isn't available when the notification center tries to
call it to send it the notification.
--
Comment:
NSNotificationCenter doesn't retain the observer. In your example, foo is
garbage collected before the notification. You must keep a live reference
to foo.
This is a common Cocoa pattern. Observers, delegates & friends are always
weakly referenced.
--
Ticket URL: <http://www.macruby.org/trac/ticket/484#comment:1>
MacRuby <http://macruby.org/>
More information about the MacRuby-devel
mailing list