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.
Related
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!
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.
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.
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.
Does a method which I check for with respondsToSelector have to actually exist?
What if I only define it in the interface part and fail to implement it? I'm looking at a poor-man's virtual function in Objective-C.
First, yes the method actually has to exist for the check to succeed in the context you describe. respondsToSelector: will return NO if the method is not implemented.
More importantly, I think you mean a poor man's pure virtual function in Objective-C. All instance methods are "virtual" in Objective-C; since method lookup is done a run-time, the subclass' implementation will always be used, even from a pointer of the superclass type. In Objective-C, there is no such thing as a pure virtual base class. You can often achieve what you want by either using a #protocol to define an API or using a base class that provides an implementation that throws an NSNotImplementedException as its body. Subclasses would obviously have to override the implementation, making it effectively pure virtual.
Given that calling respondsToSelector: only makes sense when you don’t know whether a method exists, it’s not entirely clear what you mean.
If you mean, does some implementation of a method with the specified selector have to exist somewhere, the answer is no. Selectors merely represent names of methods. The #selector directive doesn’t reference any aspect of any method implementation.
respondsToSelector will return NO, since the selector isn't callable at run-time. The interface part only affects compilation.