Events & Blocks
RemObjects Iodine extends Java language with support for .NET-style Events via the __events
keyword.
Events are provided mainly to let Java fit in well on .NET, where the use of them is unavoidable. But although events most commonly used in .NET and both Cocoa and Java have different paradigms to deal with similar concepts such as Blocks and Delegates, Delegate Protocols (Cocoa) and Anonymous Interfaces (Java), events are supported in Java on all platforms.
Declaration Syntax
Events are pretty similar to properties in concept, and that reflects in the declaration syntax. An event member is declared similarly with the __event
keyword, followed by a name for the event and the event type, which must be a Block type:
__event EventHandler Click;
Like properties with short syntax, the compiler will take care of creating all the infrastructure for the event, including private variables to store assigned handlers, and add and remove methods.
Assigning Events
Externally, code can subscribe or unsubscribe from receiving notifications for an event by adding or removing handlers. This is done with the special +=
and -=
operators, to emphasize that events, by default, are not a 1:1 mapping, but that each event can have an unlimited number of subscribers.
func ReactToClick(aEventArgs: EventArgs) {
}
//...
myObject.Click += ReactToClick
//...
myObject.Click -= ReactToClick
The +=
operator adds the passed method (also called event handler) to the list of subscribers. The -=
operator removes the method from the list again, assuming it was added before. Neither operator looks for duplicates, so if +=
is used multiple times with the same event handler, that handler will trigger multiple times when the event fires. Similarly, -=
removes the first occurrence of the event handler from the list.
When the event later fires, all the subscribers that have been added will be notified. They will be called one by one, but the order will be undetermined.
Who can add and remove subscribers to an event is controlled by the visibility of the event (see below).
Calling Events
An event can be called, or fired, by simply calling it like a method. Before doing so, one should ensure that at least one subscriber has been added, because otherwise firing the event will cause a Null Reference Exception. You can check if an event has one or more subscribers by comparing it to nil
or using the assigned()
system function:
if (Click != null) {
Click()
}
Only the type that defines the event can fire it, regardless of the visibility of the event itself.
Visibility
Like all members of a type, events can be marked with a visibility modifier, such as public
, internal
, or private
. This visibility extends to the ability to add and remove subscribers, but not to raise (or fire) the event, which is always private.
Virtuality
Events are virtual, and can be overriden in base classes.
Block (Delegate) Types
Block types (for use in Events and elsewhere) can be defined using the __block
keyword:
__block int BlockTypename(int i);