The basic idea is that in all cases the observer or delegate method are called in the same thread the initial notification (for the observer pattern) or delegating code are running, so if you're not sure it's recommended to dispatch your UI block in the main thread. I will try to justify this statements in the reasoning below, of course I can be wrong.
Unless explicitly specified in the delegate protocol documentation, in the delegate pattern a method is called directly in the same thread the caller is running at the moment of the call. E.g. if the caller (delegating object) wants to call his delegate and is currently running on "Thread-1" then the call will happen in the same thread:
// this is running in "Thread-1" --> then aDelegateMethod will continue on "Thread-1"
[myDelegate aDelegateMethod]
As far as the observer pattern, I don't see any valid reason for the system to send an observing notification explicitly on the main thread, especially if the original value change that originates the notification is running in another thread. In fact in the KVO case the runtime changes the class definition by adding some private methods that override the setter methods to do the notifications, and I don't see a valid reason to do this call explicitly in the main thread. So according to me a KVO notification can originate from any thread and this thread is the same that is running the value change in the observed class.
Finally the NSNotificationCenter based mechanism sees his notifications called by the same thread where the original notification has been posted. This is clearly stated in Apple documentation (and it's worth to say that every thread has its own notification queue).
So in all cases the thread is maintained and if you want to be sure your UI block is called in the main queue then use the GCD call that you posted in your question.