Skip to content

UXNotificationObs

UXNotificationObs is one registration inside a UXNotificationCenter. You do not construct one; addObserver makes it. The centre’s lifetime guarantees are implemented here.

#use <UXKit> // or #import "UXNotificationCenter.xc"
class UXNotificationObs {
weak: Object* observer; // identity, for removeObserver
callback method void(UXNotification* note);
u8* name; // 0 = match ANY name
weak: Object* object; // 0 = match ANY sender
}

It has four fields, and three of them avoid owning anything.

observer is weak because the centre must not keep a subscriber alive: window → centre → observer → window would be a retain cycle around every window in the program.

object, the sender being filtered on, is weak for the same reason: an observer watching one document should not keep that document in memory.

method is a callback, which never owns its receiver.

A registration therefore holds nothing alive. When an observer dies its callback reads false, dispatch skips the entry, and the next sweep prunes it. For this reason removeObserver is hygiene rather than a crash guard.

Both name and object treat 0 as match anything:

field0 means
nameevery notification, whatever it is called
objectevery sender

object == 0 is the common case: “tell me about doc.changed from anyone”.

name == 0 is rarer. A registration with no name hears everything, which suits a logger or a debugging trace. The addObserver signature takes a name, so pass 0 explicitly:

nc.addObserver((Object*)tracer, &tracer.onAny, (u8*)0, (Object*)0);

Both wildcards at once means “every notification from every sender”. It is cheap to write and expensive to leave in, since it fires on every post in the process.

The centre compares notification names byte by byte, not by pointer. Two copies of the same string match, so a name read from a file, built at run time, or defined in a different compilation unit still works.

With interned pointers instead, "doc.changed" from two places would fail to match without any error.

weak: Object* observer

Identity only. removeObserver matches on it; the centre never calls it directly.

callback method void(UXNotification* note)

What gets called. It carries its receiver, so the observer field is not used for dispatch.

u8* name // 0 = any
weak: Object* object // 0 = any sender