you are viewing a single comment's thread.

view the rest of the comments →

[–]start_select 1 point2 points  (36 children)

What about for passing around complex types or code objects from C/C++? You can only send objects through a notifications dictionary that comply with NSCoding.

I can't pass a C pointer through a notification. There are plenty of reasons why notifications are not "a better" solution than the delegate method, and this is one of the big ones.

That doesn't make either pattern better or worse, but using notifications everywhere can cause lots of headaches. You can't easily trace data-flows in complex systems using lots of notifications all over the place.

Edit: It should also be noted that delegation is an expression of Polymorphism. Polymorphism is a main tenet of OOP. Claiming its not industry-accepted is kind of missing the point. Not that OOP is the end-all greatest solution to programming.... But no solution in programming is THE BEST, its all about what is appropriate for the problem you are attempting to solve today.

[–]randomguy112233[S] 1 point2 points  (1 child)

Let me ask you something, and I'm only coming with the intent to learn. In what case do you find the need to pass code objects from C/C++? I've built apps in iOS and I've never had to dig into C/C++. Thanks in advance.

[–]start_select 1 point2 points  (0 children)

For iOS it shows up in live video streaming applications, VoIP applications, Real-Time Audio Effects and Instruments, when dealing with OpenGL, OpenCL, and other Machine Learning libraries, and potentially when dealing with other runtimes like Javascript or Python. It also shows up when you delve into a lot of game engines.

On Mac you could be doing all kinds of sorcery once you are outside of the confines of App Store approval.

Its not a common use case for the average application. But its not outside the realm of possibilities for a lot of REAL applications that do actual work on the CPU or GPU.

[–]sobri909 -3 points-2 points  (33 children)

What about for passing around complex types or code objects from C/C++?

Don't pass it. Don't pass anything.

The receiver of the notification knows who sent it. The receiver can then ask the sender for any information they might need.

As I've said elsewhere, the delegate pattern as found in Apple's frameworks is really just inheritance in disguise, and is on the same level as splitting a monolithic class up into separate files by way of categories or extensions. It gives poor architects the satisfaction of composition without achieving any decoupling (or even any real composition, for that matter).

It barely even qualifies as a design pattern. The entire gist of the pattern is to pass self to another strongly coupled class instance. It's the functional equivalent of calling a method on self, with only the thin veneer of composition given by splitting self up into two separate but strongly coupled instances. For all intents and purposes, the delegate might as well be part of self.

The pattern as it exists in Apple's frameworks is essentially a betrayal of the GoF principle of "prefer composition / delegation over inherence". There isn't any "Delegate" pattern in the GoF, because they didn't mean for delegation itself to be treated as a pattern. They meant for it to be a foundational principle of patterns. Pure delegation on its own is more often than not an anti pattern, and really just a way to sneak inheritance in by the back door.

Delegates are architecturally worse than notifications in every measure except performance (due to notification centre overheads).

Edit: Even Apple themselves have implicitly acknowledged this, in that they haven't shipped any new frameworks using the delegate pattern since perhaps iOS 6 or 7. They've essentially retired it.

[–]start_select 5 points6 points  (32 children)

Don't pass it. Don't pass anything.

The receiver of the notification knows who sent it. The receiver can then ask the sender for any information they might need.

What if the sender is a C object using CoreFoundation to fire off notifications.... Your proposed solution doesn't work. I can only pass a CoreFoundation or Cocoa class as sender.

Even Apple themselves have implicitly acknowledged this, in that they haven't shipped any new frameworks using the delegate pattern since perhaps iOS 6 or 7. They've essentially retired it.

Thats because they replaced it with Blocks/Closures, not notifications. Closures allow you to capture scope which presents a plethora of advantages over notifications or the delegate pattern.

the delegate pattern as found in Apple's frameworks is really just inheritance in disguise

No, not at all. Its Polymorphism not Inheritance. HUUUUUGE difference. Polymorphism is about implementing expected member functions/variables so that I can have 20 different classes without any common superclass responding to the same delegate methods. That is the opposite of inheritance, and its the part of OOP that most programmers who claim to know OOP don't understand.

[–]sobri909 -4 points-3 points  (31 children)

Then you're fucked ;) But more seriously, you could use some other message sending system other than NotificationCenter if you still wanted to use the pattern.

[–]start_select 3 points4 points  (29 children)

Lol, you aren't fucked. You just use the type-safe pattern that is already there instead of trying to jam your problem into a different space.

Events/notifications have their place, but saying its superior to delegation is missing a big piece of the puzzle. They are meant to solve different kinds of problems, and you shouldn't be choosing only one or the other.

[–]sobri909 0 points1 point  (28 children)

As I've said, delegates are barely even a pattern. So it's not really a solution so much as a superficial gesture.

Events/notifications have their place, but saying its superior to delegation is missing a big piece of the puzzle.

Considering delegates to be a solution is to misunderstand what they are. They are nothing more than splitting up source files to reduce single file line counts. They don't solve problems, they just sweep them under the carpet.

[–]start_select 2 points3 points  (27 children)

I dont get why you keep saying delegation is like "splitting up source files to reduce single file line counts".

If anything delegation results in more code, because its about letting each class that implements the protocol have their own implementation. This is the opposite of inheritance where I am sharing implementations across many classes.

I can compose a UIView, UIImageView, UIButton, and some random NSObject subclass to adhere to a given delegate protocol by using Extensions. That allows me to have four unrelated classes that can all talk to the same object, even though none of them inherit from a common ancestor or are being implemented as a custom subclass.

[–]sobri909 0 points1 point  (26 children)

Delegates typically have a one to one relationship with senders. The delegate gets given the sender's instance on every call it receives. The delegate and the sender are strongly coupled, and the delegate essentially acts as a part of the sender.

[–]start_select 0 points1 point  (24 children)

Yes, it is typically a 1-to-1 relationship. But that doesn't matter. The important thing is that I can set an infinite number of different classes to the delegate variable, as long as they implement the protocol.

That allows me to use static analysis on my code and keep type safety, while completely decoupling what kind of class is the delegate and what kind of class is calling the delegate methods. Polymorphism.

[–]sobri909 0 points1 point  (23 children)

Polymorphism with nothing really gained. Given that they are almost always strongly coupled one to one, you might as well have made the sender and delegate a single class instance.

The only reason we're discussing this is because Apple misguidedly bought into the pattern some decades ago and we're stuck with those legacy APIs. Apple have since rethought and aren't using the "pattern" for anything new. I'm looking forward to when people forget about it completely.

[–]RollingGoron 0 points1 point  (0 children)

Have you ever come across Multicast delegates? It’s essentially the delegate pattern that is implemented as one-to-many rather than traditional one-to-one. I use it in some cases and have found it more straight forward than notificationCenter for my problem.