Override a method in a single object instance - objective-c

Am not sure how to put this, and I couldn't find the answer because of my inability to find the words to express what am looking for. (!)
In Java, I used to do something like this (I don't remember):
JPanel myButton = new JPanel("Press me"){
public void add(JComponent component){
//override add method
}
};
But, i couldn't find how to do this in Objective-C .. What I found in my search was categories and weird ^{} symbols ...
So, how can I override method(s) in a newly created object?
(For example, override -(BOOL)isEqual; in a newly created NSString* ?)
Am sorry if the question is a bit vague..
EDIT:
Obviously, without subclassing :)
EDIT:
Might as well post my problem in case someone has a better idea:
I have a few CCTransitions in COCOS2D, and I want to be notified when the transition ends .. The thing is, as soon as the transition ends, the -(void)finish; method is invoked (which is part of the CCTransition class structure)
I would really want to avoid subclassing the CCTransition class, and override the finish method to do my logic when the transition ends :)
EDIT:
-(void)onEnterTransitionDidFinish; ... I can't believe something as awesome as that existed and I haven't came across it while searching......
Which means, instead of subclassing CCTransition, override this method in my CCNode subclass :D!

It's still not going to be very clean, but assuming you're willing to concentrate the ugliness, you could do something like (untested):
Method methodToReplace =
[targetClass instanceMethodSignatureForSelector:#selector(methodToReplace)];
IMP implementationToSet =
[someProxyClass instanceMethodForSelector:#selector(implementationYouWant)];
method_setImplementation(methodToReplace, implementationToSet);
Relevant reference documentation is the Objective-C Runtime Reference and, optionally, the NSObject Class Reference (because it makes a few things slightly neater, though e.g. you could use class_getInstanceMethod from the runtime rather than instanceMethodSigntureForSelector:).
Note that you'll have no way to call the original implementation if you use exactly that recipe. method_setImplementation returns the old implementation, it's generally wise to add that to the class under a brand new selector and call that instead.
For reference, I've had a legitimate reason to do this sort of thing only exactly once: when we implemented printing support in an iOS application with which needed to be compatible with both OS 3.2 and 4.0. You need to subclass a particular class, but the class isn't available in 3.2. So you sort of have to subclass at runtime (though the conceptually neater way would be to use a normal subclass, put that into a framework and weak link, but Apple's iOS SDK terms allow static libraries only, so...).

Following Daniel's suggestion, you can implement a method in an NSObject category of the form
[anObject overrideMethod:#selector(foo:)
byBlock:^(id self,id super,id originalArg){
...
}];
What you need to do is to
objc_allocateClassPair against self's own class, to create a new temporary class
Turn a block into a function pointer, using e.g. this or this
method_setImplementation to set the new implementation to the temporary class
use object_setClass to self to set the class to the new temporary class
I haven't figured out how to provide super to the block :p
It's believed this is basically how the KVO is done by Apple, see e.g. this discussion.
Read Runtime reference.

What you have there in Java is an anonymous subclass. This is not possible in Objective-C (well, it sort of is but you would have to do some pretty involved contortions with the Obj-C runtime library).
But Objective-C as of iOS 4 or OS X 10.6 has "blocks", which is what the ^{} syntax is for. This is Objective-C's notion of a closure. This isn't going to help you directly if the APIs that you're calling don't support block callbacks, but you may be able to create wrapper classes that use blocks instead of subclassed methods to handle callbacks.
There are many resources for learning about blocks in Objective-C.

Related

objective-c override system method

I find a c++ system method causes crash in ios and I try to swizzle the method. However, I do not how to do that because it's a method of a c++ class. Anyone know whether can I do that?
Method swizzling is unique to objective-c (and even there one has to use it carefully), and is not applicable to c++.
I suppose that you don't have access to the source code of the c++ class.
Then the only way to "exchange" the implementation of a method at a specific c++-class is to derive a subclass, override the method, and then make sure that the subclass is used instead of the other class. It is still unlikely that you have a chance; the method being not virtual, the class to be replaced being used in non-polymorphic ways, the class to be replaced already having several subclasses, each of these points will prevent you from being successful.
Good luck though!

Methods required to be implemented when subclassing in Objective C

I am new at programming in general (though I have had a C class many, many years ago) and am learning Objective-C for programming on the iPhone. I have what I think is a simple question, but after looking for a while (days, off and on) I can't find the answer that I'm looking for explicitly.
I know that when subclassing an Objective-C class I should implement the initialize method along with the deallocate method (unless using ARC for the latter, if I am correct?). The questions are:
Are these the only two to worry about, or will other classes potentially have additional methods that can be required to be implemented?
If other classes might have methods that I am required to implement when subclassing them, where is that documentation typically found? (I don't seem to see that in the Apple framework docs, though that kind of information is there for protocols it appears)
Thanks for your help!
Technically, you are not required to implement even the init and dealloc if the inherited versions are sufficient. Also, ARC does not free you from having to write dealloc in all cases (but it certainly covers the overwhelming majority). For example, if you allocate memory for your object using malloc, you need to free it in the dealloc.
When you add instance variables to your class, you need to initialize them. Typically, you do that in a designated initializer. Again, if you do not to initialize anything, you do not have to code your own initializer; same goes for deinitializer.
The only case when you need to implement a method is when you adopt a protocol with one or more methods marked #requried. These methods are marked in the protocol reference. For example, tableView:cellForRowAtIndexPath: and tableView:numberOfRowsInSection: are marked with the "required method" tag in Apple's documentation.
No methods are required when subclassing an NSObject (or any of their subclasses, such as UIViewController, UIView, etc. etc.).
If you create a new, let's say UIViewController, it's generally a good idea to keep the methods you find in the newly created file as a guideline/template, but you're not really required to keep any of the methods. The super class will always call the methods on itself.
Be aware, though, some methods you have to call super, like viewWillAppear, etc.

If Protocol method is marked #required, when not implemented, why does compiler issue a warning and not an error?

Assume that:
New Protocol is declared
Method in this protocol is marked #required
Class conforms to Protocol
Class does not implement the method mentioned in Protocol
At compile time, information about this method is known: i.e. that it is required and that this class and any other classes this class may may extend do not implement it.
Why in this case the compiler issues a warning and not an error?
Errors are only issued when the compiler cannot continue because something went terribly wrong.
When calling a method in Objective-C, the method lookup is done during runtime and not during compilation, which C++ does. In Objective-C a "message" is simply sent to the object, something like obj.executeCommand("Hey, can you execute function <name> for me?"). In C++ the object will be called directly, in a way like obj.<name>(). In the case of Objective-C the executeCommand() method is called, which exists. In C++'s case the function is called but it does not exist. These are methods that are linked on the compiler level, which means they both become memory addresses rather than names. executeCommand becomes 0x12345678 but it still uses the same message ("execute function <name>").
This is probably very confusing, but it's related to the way methods are implemented in different languages.
If you feel strongly about it, why not turn on -Werror?
I don't know the real answer but here is a use case that would go against it.
What if you implemented all of the protocol methods in a category???
Main interface declaration adopts the protocol however the protocol method implementation is in a category.
This is valid code but will show compile error if compiler was that strict !!
Objective-C is a dynamic language. The idea of what an implementation is, is different to a static language.
For the most part, it's in code that most of us implement inside the #implementation ... #end block.
But what if a method is not found? Then an object has a chance deal with it dynamically.
Imagine you have an interface for a sound effect player:
#protocol FX
- (void)playBeep;
- (void)playSiren;
- (void)playHonk;
#end
An implementation could have the files Beep.mp3, Siren.mp3, Honk.mp3 to play, but instead of implementing each of the methods, it could override -forwardInvocation: and parse the selector string, something like this pseudocode:
NSString *selName = NSStringFromSelector([invocation selector]);
if ([selName startsWith:#"play"]) {
NSString filename = fileNameFromSelector(selName);
[self playSoundFileNamed:filename];
}
This may seem contrived, but once you start using the dynamic features of the language, you will start finding more and more places where it makes sense. And by sense I mean, does this effort help in the long run?
In the above case, just add a -sound* method name to the interface, and drop in a appropriately named sound file. It just works.
Another example from personal experiments: how to deal with Core Data entities in a more natural way. I want to do this:
NSArray *people = [Person findAllWithNameLike:#"B%"];
instead of mucking about with predicates, fetch requests etc.
But I don't want to define every permutation of method in code.
How about if I wanted to build an XML builder? I would look at a dynamic approach. It has served Groovy Builders well (look at Groovy/Grails for examples).
One last example: I have a traits system where I can define behaviours in the form of groups of methods and have my objects assimilate this behaviour. So, while the compiler doesn't see an implementation for the interface my object conforms to, the implementation is injected into it from a trait class, using the Objective-C runtime. Why would I do this? I find many delegate methods are boiler plate, but at the same time, a single base class for each situation is not flexible enough. Instead of cut and paste from code samples, my 'samples' compile and run :) and any changes are reflected across all projects using the trait.
To really understand why all this is available to you, it is worth playing around with a Smalltalk environment (search Pharo or Squeak). This is where Objective-C has its roots.
And finally, to stop these warnings:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wprotocol"
#implementation ... #end
#pragma clang diagnostic pop
Because there are times when there are bogus "required" methods in a poorly designed protocol.
They should have been optional but someone insisted they are "required".
Thusly making this a run time issue rather than a compile bug is very very wise.

About methods overriding a method in the superclass without implementation

I have a class with several subclasses.
They all override a class method, but I don't have a specific implementation for the method in the superclass.
Since I can't just declare it in the interface but I need to implement it as well (to avoid debugger warnings), I was wondering if I can just provide empty implementations of the method in the superclass.
The reason why I'm adding the methods definitions to the superclass is that I've a multi-target project, the current application delegate is considered with the specific overridden method:
[(GenericDelegate *)[NSApp delegate] myMethod];
thanks
Yes, this is a perfect normal practice. In fact, it has a name: a "Template Method." You search for that in the Cocoa documentation.
You will find that Apple also does it occasionally in their own code. The drawRect: method in UIView is the first one that comes to mind.
So, anyway, yes, if it suits your needs, I would go ahead and do it. Just make sure that you think through whether or not, for example, a protocol wouldn't suit your needs better.
There are other options as well. Check out the answer/discussion over here: Does Objective-C have something like C++ virtual functions?
All methods are virtual in objective c, "pure" virtual (as in C++) function don't exist and hence the equivalent methods in objective c need an empty implementation in the superclass, just to silence the compiler warning (I don't think there is any other way to do so). There is nothing wrong with that. This post is related to your question.

Is the use of header-less method implementations good practise or frowned upon?

If you write method implementations in Objective-C, it is pretty standard to sum up the methods of a class in the corresponding #interface blocks. Publically accessible methods go in the header file's interface, not-so-public methods can go in an empty category on top of the implementation file.
But it's not neccessary to declare an interface for every method. If you only reference the methods below their implementation code of the same class/file, there's no need to put any declaration anywhere else.
-(void) doSomething {
}
-(void) doSomethingElse {
[self doSomething];
}
Coming from another language, this is new to me. And I can't seem to decide whether it is nice and pretty to keep the interface blocks clean, or whether it should be prevented because the order of method implementations seem like a weird dependency to have.
What is the general public's opinion of this matter?
The general rule I follow is that if the only method calling doSomething is doSomethingElse then it's fine to not have doSomething be part of the declared private interface. But the moment a second method makes use of doSomething I add it to the declared interface.
The thinking behind this is that as long as the method is only ever called from one place there's no reason to think of it as modular or reusable code. Instead it's more like the method exists just to tidy up the implementation of its calling method. In essence, the method doesn't really stand on its own, so there's no point in treating it like an interface method. But as soon as a second method is making the same call it demonstrates that the code is in fact reusable and useful in more than just the original context, and able to stand on its own as a useful function. So at that point, it becomes a declared part of the private interface.
Some other coding style choices make answering this question really easy:
If you document every method at its declaration point, then not having a declaration means that either these methods are missing documentation, or they are documented at definition; either way it's inconsistent. If you follow the school of thought that most methods should be so self-explanatory from their name that they don't need documentation, this might not be an issue.
Some people advocate ordering methods from more general to more specific; in that model your example is ordered wrong, and the only way to fix it is to have a declaration.
There's also the question of whether you would find it annoying to get unexpected compiler errors when you do simple re-ordering or re-factoring just because you happened to start using a method earlier, and have to stop and add the declaration at that point.