I have a handful of classes that manage some data. They all sync with a server, and the sync is started by one method called startSync. I want the super method to do some checking if the sync is even necessary, and if it isn't to stop the sync before the child method kicks off the sync.
I have thought of a few options, but not sure which one is the best way to implement it. I'm working in Objective-C so that adds a few variables to consider.
A) Make the method return a boolean value and have the child implementation call the super implementation and check the boolean, returning false if it is false. But someone writing a subclass and implementing the method won't always know what to do with that.
B) Make a doSync abstract method that the super class calls from the startSync method that one would call from outside the class. This has the side effect of not knowing which method to call and accidentially overriding the wrong method.
C) Same as B but the "doSync" method is protected by using an "internal" header. This has the side effect of accidentally overriding the wrong method because they don't know about the internal header, but outside classes don't know about the doCall method to skip the check.
What I'm looking for is input on if one of these is the most appropriate or if there is a better option.
Related
I have next issue:
I have a decorator for the NSButtonCell class, which adds some functionality. As it is a decorator - is's a subclass of NSButtonCell. I didn't like to create subclasses, because the same functionality must be dynamically added\removed to some other subclasses of NSButtonCell. And, as it is a decorator, I must forward all messages to the decorated object, because some subclass can have own 'setting', behaviour and etc. Because NSButtonCell has many methods, I can't write code to redirect all messages to decorated object. Please, tell me, how I can redirect all received messages to decorated object?
Round Peg meet Square Hole.
The reason why you are finding it so hard to do this is because it is an exceedingly non-standard pattern to use for implementing UI. Method forwarding as implemented by either forwardInvocation: or NSProxy is useful, but pretty much never used to implement the Decorator pattern in the context of the UI.
While you could use a subclass of NSProxy that selective forwards or implements the methods you need, that is a complete waste of code compared to simply creating a subclass.
Just use a subclass and be done with it.
However, only subclass if you really need to. If the provided NSButtonCell can do all that you need and it is merely a matter of configuring it, then configure it in your controller or in whatever mechanism that you use to layout and present your user interface.
And in your case, it sounds like a central controller or UI configurator is the way to go as that will centralize the functionality into a single spot that can then control multiple (potentially minimal subclasses) instances of the various UI classes.
Using NSProxy is the standard approach for creating objects that act as stand-ins for other objects or objects that don’t exist yet. Its entire structure is based around handling methods and forwarding them to the true object.
So I've had to subclass NSURLProtocol because I am using a UIWebView and want to intercept ajax calls which works fine as per this example. I have to get the data from the request from + (BOOL)canInitWithRequest:(NSURLRequest *)request which causes a problem, I now need to call instance methods to do things with the data, but I can't because it's a class method.
How could I call an instance method based on the contents of what is in the request?
You cannot call instance methods from a class method without having an instance first. This is true for all object-oriented systems, AFAIK. After all, the instance methods (usually) use data that the class method cannot have. Imagine an object with a property name, and you now have one thousand objects with different names. How should the class method know which name to use?
So you need to find a way to somehow query instances of your class based on your request, or find a way to get at the information in a way that does not involve instance variables (if a method doesn't use instance variable you can turn it into a class method or even C function). There are many different ways to solve the "query problem", which to chose is highly dependent on your design and even taste.
canInitWithRequest: shouldn't do any work whatsoever, it should just respond with "YES" or "NO". "startLoading" is where you do the work.
If I follow any of a number of examples available on the web, I see a common theme emerge with the delegate pattern:
myClass.delegate = self;
From what I read, delegation is supposed to uncouple behavior, but allow interaction between classes, however, only assigning a single delegate seems to be 100% at odds with this behavior.
I have a web dev background, and I am intimately familiar with pub/sub patterns, but what I'm trying to wrap my head around is why I would only allow a single delegate (self) to be able to act on whatever happens in myClass. That would seem to ruin the entire point of delegation.
Maybe I'm misunderstanding something, or maybe this is only the simplest form of delegation, but could someone please explain how statically assigning (in the classic sense) one class to another's delegate decouples behavior in any meaningful way.
Bonus: Perhaps a way to allow multiple classes to act on a delegation.
The delegate asserts additional control over the delegated class. The most simple example is windowShouldClose: method in the NSWindowDelegate protocol. The class delegate gets a chance to proactively override closing the window in NSWindow. If multiple delegates were allowed, multiple delegates could supply conflicting orders which would be an undesirable result.
Delegation allows you to customize behavior without subclassing. Because a class can implement many delegate protocols, it is a key part of the MVC programming model in Objective-C. Delegation allows you to create one class as a "Controller" of multiple other classes.
For acting reactively to what happens to the class, you use a pub/sub model of key value observing. For example, NSOperationQueue has an observable property operationCount to let you react to changes in the number of operations in the queue.
It decouples behavior in the sense that the delegator needn't know anything at all about the delegate other than that it (possibly) responds to a certain set of methods. This makes it so that classes that have delegate can be used in entirely different codebases/situation without changes. It's particularly applicable when writing Framework classes that will be used by someone else, which is one reason you see it so much in the system frameworks.
One of the major uses of delegation is to allow customization of an object's behavior without subclassing. Take for example the NSWindowDelegate method -windowWillResize:toSize:, where the delegate can return a different size than the suggested one to implement custom sizing behavior. How would this scenario be handled with multiple delegates each returning a different value?
Of course, sometimes delegate methods are merely meant to inform the delegate that some particular event has occurred. In these cases, it is indeed reasonable for multiple objects to want to be notified. This is provided for in Objective-C/Cocoa by notifications (NSNotification), and Key Value Observing (KVO). You'll find plenty of cases in Cocoa where a delegate method also has a corresponding notification posted in case objects other than the delegate want to know about it (e.g. windowWillClose:/NSWindowWillCloseNotification).
Say I have an class which has three states: full screen, windowed, and minimized. The state of my object is stored as an enumerated type,
typedef enum {
StateFullScreen,
StateWindowed,
StateMinimized
} State;
If every time I change the State, I am calling two methods: setState: and showState:, should I couple these actions into one? For example, override the normal synthesized setState: method and have it depending on the state call the proper showState: method? Or should I do it the other way around having showState: call setState:?
Are either of these good programming practice when it comes to object-oriented design?
Have you considered creating a ChangeState(...) method?
It would be simple enough to create a first pass refactoring that calls the other two methods. I'd then work through further refactorings to clean it up fully.
In my opinion it would be better to do all the work in setState, this is what someone using your class would expect.
I have a session class, which has statusses connecting, disconnecting, online and offline. If I call setStatus it will also call a delegate method and disconnect the session if the new status is equalto disconnecting or offline.
I am looking to write a plugin controller in Cocoa that loads bundles, and exposes a specific set of methods for the plugins to call.
My question is this: is it possible to know (any) info about the object that called a method in the controller. When an instantiated plugin calls a method in my plugin controller, I would like to know which of the plugin instances called the method, without having to rely on the plugin sending a pointer to itself as a parameter (I could always validate the pointer they send, but I want to keep the API methods as simple as possible).
There may be no perfect solution (and there are simple workarounds), but it's always good to learn some new tricks if possible (or the reasons why it's impossible).
Thanks in advance.
It's not possible without walking the stack, and possibly not even then. There's not even a guarantee that a given message was sent from within a method — and even if it was, it may not be the method that you think of as being the "caller." For example, assuming your plugins have access to Cocoa, your controller methods could be called by an NSTimer.
In general, this is not practical. The normal way to accomplish this is to have objects pass themselves around. If you're trying to do this for security reasons, you'll want a much more robust solution anyway, because Cocoa's object model was not designed with that in mind. It's way too easy for objects to lie about who and what they are.
Well, you could throw an exception, catch it and examine its stacktrace.
Assuming that Objective-C supports exceptions, of course.
Sending a reference to the calling object is how this is usually done. As an alternative, you could have your host code provide a proxy object for plugins to talk to. As each plugin is loaded, create a new proxy object for each to talk to.