How to avoid superclass methods getting overridden by sub class in objective - c - iphone

Like in java:
A final class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes are final, for example java.lang.System and java.lang.String. All methods in a final class are implicitly final.
How can I achieve this behavior in objective-c?

You can't. Efficiency doesn't come into it. If you are that bothered about security don't use objective-c. There will always be a way to get around any measures you take.

As has been said a number of times, you can't.
However, if you are making a library (which is the only case in which I could see this being relevant, anyway) there are a few steps you can take. Well, one, really.
Write, in the documentation of the class, that "This class is not intended for subclassing." (ref. NSIndexSet) or "Do not override this method." (ref. +[NSApplication sharedApplication].
As a way of explanation, it is worth noting that (pretty much) everything that happens in Obj-C, and that separates it from C, happens at runtime, and the runtime is, so to speak "Right There". Any piece of code can inspect, mutate or pervert the runtime at their leisure, making Obj-C a terribly powerful language; especially with regards to its "meta-language" structure.

There is no final equivalent in objective-c. There are same patterns that might be good alternative, they'll give you better separation, but neither performance nor security:
If you only want to allow certain methods to be overwritten using delegate pattern might be a better choice.
If you do not want subclassing at all, then you can use the abstract factory pattern. Declare a public interface + factory methods, and hide the concrete implementation classes.

It seems that around 2019 objc_direct attributes are available, which can be used for final methods, and remove runtime limitations
You can read more about these attributes at NSHipster, or in the original Twitter thread
#interface Base: NSObject
- (void)cannotBeOverridden __attribute__((objc_direct)); // final
#end
#implementation Base
- (void)cannotBeOverridden { }
#end
#interface Child: Base #end
#implementation Child
- (void)cannotBeOverridden { } // Error here
#end

Related

Objective-C Private Method Dilemma

I'm aware that Objective-C doesn't support real private methods. What I'm currently doing to declare 'private' methods is adding the following to class .m files:
#interface MyClass()
- (void) privateMethodName;
#end
The Problem:
If I now add a subclass, and want to use this 'private' method, I can't! I get the error:
Receiver type 'SubClassName' for instance message does not declare a
method with selector 'privateMethodName'
So, if I don't want non-subclasses to be able to access this method, but do want subclasses to be able to, what can I do? What is the best/proper way of achieving my goal?
You could separate the "protected" interface from the public one. In the primary header, just declare the public methods:
MyMagicThingy.h:
#interface MyMagicThingy: NSObject
- (void) publicMethod;
#end
Then, have an additional header with protected methods:
MyMagicThingy+Protected.h:
#import "MyMagicThingy.h"
#interface MyMagicThingy (Protected)
- (void) protectedMethods;
#end
You cannot have "real" private/protected/public methods in Objective C (as in: the compiler will enforce access rules. All methods are public). You have to go with a convention.
What you describe is really a protected method. One approach to overcome this: Ivars can be declared #public, #protected, or #private. You could declare a protected helper instance to restrict access to derived instances, which then calls back through the object which holds it.
Another alternative in some cases would be to make the subclasses write to an interface, then keep your implementation private.
Sometimes, you just have to document "don't do this, unless you are not a subclass" because it's not part of the language. In this mindset, a separate header which declares a category of protected methods is one of my favorite. It's pretty well hidden from clients, but can be made visible to subclasses by explicit inclusion -- Dirk provided an example of this at the same time, check it out.
Lastly, if you're comfortable with ObjC++, C++ offers this control, so you can mix modes and visibility quite freely.
First and foremost
You can't get anyone to not being able to call any method that is implemented on an object in Objective-C (at least not without burning through several dozen razors making Yaks less weatherproof).
Just don't call methods that are not declared in public header files, as a convention (this is, what you're already doing).
Second
The word public in the above paragraph does the trick:
In Objective-C (at least in its current incarnation), a class's interface can be defined over any number of header files using the technique you just described in your post: Class continuations.
One such example of an Apple framework class doing that would be UIGestureRecognizer with its separate subclassing header UIGestureRecognizerSubclass.h.
PS:
The error you are seeing reeks of using ARC so your runtime is definitely recent enough to even use multiple implementation files for that.

Redeclaring/extending typedef defined in Objective-C protocol in class conforming to protocol

I have an Objective-C protocol:
typedef enum {
ViewStateNone
} ViewState;
#protocol ViewStateable
- (void)initViewState:(ViewState)viewState;
- (void)setViewState:(ViewState)viewState;
#end
I'm using this protocol in the following class:
#import "ViewStateable.h"
typedef enum {
ViewStateNone,
ViewStateSummary,
ViewStateContact,
ViewStateLocation
} ViewState;
#interface ViewController : UIViewController <ViewStateable> {
}
#end
I won't go too far into the specifics of my application, but what I'm doing here is typedefing an enumeration in a protocol so that the protocol's methods can take an input value of that type.
I'm then hoping to redeclare or extend that typedef in the classes that conform to that protocol, so that each class can have their own view states. However, I'm running into the following two errors:
Redeclaration of enumerator 'ViewStateNone'
Conflicting types for 'ViewState'
I'm ashamed to admit that my knowledge of C (namely typedefs) is not extensive, so is what I'm trying to do here, firstly, possible and, secondly, sensible?
Cheers friends.
It is neither possible nor sensible. This comes from the fact that typedefs and enums are basically just defines. (Well, not really, but for this purpose, they are.) If you need to do things like this, you might want to review your design (see below).
More info
typedef type newtype;
is (almost) equivalent to
#define newtype type;
and
enum {
ViewStateNone
};
is basically the same as
#define ViewStateNone 1
There are a few finer points withe regards to differences between the two, and the most compelling argument for using enums and typedefs is of course compile time checking of integer constants.
However; once an typedef enum {} type; has been seen, it cannot be unseen, and once it has been seen, its name is reserved for it, and it alone.
There are ways around all of this; but those are paths rarely traveled, and generally for good reason. It quickly becomes incredibly unmanageable.
As a solution, you might want to create a new class, MyViewState, which represents a view state and associated information, which could easily just be a wrapper around an NSInteger.
In closing: Review your design. I fear you might be doing something overly convoluted.
It's certainly not possible in the form you have it, for reasons that the errors fairly succinctly explain. An enum constant can only be declared once in any scope, and similarly a typedef.
Moreover, there's a bit of a conceptual difficulty with defining a type in a protocol that implementors can then redefine. The implementors should be conforming to the type, not adding to it. If the class needs to be able to determine its own set of values, the protocol must use a type that is general enough to hold all those that might be wanted. In this case you could use int or, probably more sensibly, something readable like NSString. You might also add another method to the protocol that will report back the values supported by the implementing class.

Is it good style to declare methods in .h when they're intended to be overwritten by subclass?

I have a class which is intended to be abstract. This means: When someone subclasses it, a few methods MUST be overwritten.
But on the other hand, those methods are not intended to be called manually from anywhere except inside the abstract class (the superclass of the subclass).
Must I declare these methods in .h anyways or can I just add comments in .h which say "you must overwrite -foo and -bar"? Or is there a better pattern to make abstract methods?
Related: Is there a way to create an abstract class in Objective C?
Objective-C doesn't actually have a way to declare a class as abstract. From Apple's Docs:
Abstract Classes
Some classes are designed only or
primarily so that other classes can
inherit from them. These abstract
classes group methods and instance
variables that can be used by a number
of different subclasses into a common
definition. The abstract class is
typically incomplete by itself, but
contains useful code that reduces the
implementation burden of its
subclasses. (Because abstract classes
must have subclasses to be useful,
they’re sometimes also called abstract
superclasses.)
Unlike some other languages,
Objective-C does not have syntax to
mark classes as abstract, nor does it
prevent you from creating an instance
of an abstract class.
The NSObject class is the canonical
example of an abstract class in Cocoa.
You never use instances of the
NSObject class in an application—it
wouldn’t be good for anything; it
would be a generic object with the
ability to do nothing in particular.
The NSView class, on the other hand,
provides an example of an abstract
class instances of which you might
occasionally use directly.
Abstract classes often contain code
that helps define the structure of an
application. When you create
subclasses of these classes, instances
of your new classes fit effortlessly
into the application structure and
work automatically with other objects.
So to answer your question, yes, you need to place the method signature in the header, and should implement the method in the base class such that it generates an error if called, like the related question's answer states.
You can also use a protocol to force classes to implement certain methods.
However you choose to implement the base class, clearly document in the header, as well as in your documentation, exactly what the class assumes and how to go about sub-classing it correctly.
Whenever possible write your code so that improper implementations fail to compile. If you cannot do that then you should try to generate a runtime error (at the very least in a debug build) if the subclass is not written correctly. Do not rely on comments because people will not read them.
You must declare your "protected" and "abstract" methods in a header file, but you can use separate categories to clearly indicate their purpose and intended use.
#interface MyBaseClass : NSObject {
}
- (void)foo;
#end
#interface MyBaseClass(ProtectedMethods)
- (void)bar;
#end
#interface MyBaseClass(AbstractMethods) // Subclasses must implement
- (void)internalBar;
#end
You can put everything in a single header, or you could put your protected and abstract declarations in a separate "protected" header, say MyClassProtected.h, meant to be included only by your subclass implementations. It depends on how badly you want "hide" your protected methods.
Your base class can log, assert, or throw when an abstract/pure-virtual method is called.
As other people have said, Objective-C does not support pure virtual classes.
You can enforce pure virtual behaviour at runtime though. The cleanest way to do this is by using the Objective-C runtime's _cmd and NSObject's -doesNotRecognizeSelector:
- (void)iMustBeImplementedInaSubclass;
{
[self doesNotRecognizeSelector:_cmd]; // Pure virtual
}
As ben says you are probably better served by using a protocol to get your API design right.

#properties question on iPhone development

From what I've read, #properties and #synthesize are used to tell the compiler to to generate getters and setters for various properties of our class.
So I am confused when I see the source code of an Apple example, the GKTank, that uses only one class for the whole game (apart from the app delegate) and still most of the attributes of that class are defined in #property() and are synthesized, even if no other class will try to get/set them. What am I misunderstanding here?
Thanks
Using properties is generally good practice as the synthesized setters will do the right thing when it comes to memory management (retain, or simply assign, depending on how you've configured your property).
They are also a means of providing a clean separation between the public interface of your class and it's internal implementation.
This article offers some good advice on when and why to use properties and dot-notation.
It also allows you to use the dot syntax:
self.myProperty = something;
I don't know that particular example. However, it is considered good style to access members of the same class through accessors rather than referencing the members directly. By encapsulating the members as a property with getters and setters, the implementation details of the field may change while those details are abstracted by the getter/setter.
Furthermore, the declaration of properties on the class allows you to use the .-notation to access the properties so it might lead to more consistent code if you want to use that notation.

When the use of an extension method is a good practice? [duplicate]

This question already has answers here:
Closed 13 years ago.
Extension methods are really interesting for what they do, but I don't feel 100% confortable with the idea of creating a "class member" outside the class.
I prefer to avoid this practice as much as I can, but sometimes it looks better to use extension methods.
Which situations you think are good practices of usage for this feature?
I think that best place for extension methods is "helper" methods or "shortcuts" that make existing API easier and cleanier by providing default values to arguments of existing methods or hiding repeating chains of method calls.
Contrary to the common beliefs that you can "extend" classes for which you do not have access to the source code, you cannot. You have no access to private methods and objects, all you can do is to polish public API and bend it to your likings (not recommended).
They're great for interfaces (where you can add "composite" behaviour which only uses existing methods on the interface) - LINQ to Objects is the prime example of this.
They're also useful for creating fluent interfaces without impacting on the types that are being used. My favourite example is probably inappropriate for production code, but handy for unit tests:
DateTime birthday = 19.June(1976) + 8.Hours();
Basically anywhere that you don't want to or can't add behaviour to the type itself, but you want to make it easier to use the type, extension methods are worth considering. If you find yourself writing a bunch of static methods to do with a particular type, think about whether extension methods wouldn't make the calls to those methods look nicer.
When the class is not extensible and you don't have control over the source code. Or if it is extensible, but you prefere to be able to use the existing type instead of your own type. I would only do the latter if the extension doesn't change the character of the class, but merely supplies (IMO) missing functionality.
In my opinion, extension methods are useful to enhance the readability and thus maintainability of code. They seem to be be best on entities where either you have no access to the original class, or where the method breaks "Single Responsibility Principle" of the original class. An example of the latter we have here is DSLs. The DSL models are extended with extension methods are used to make T4 templating easier but no methods are added the model unless they are specifically related to the model.
The ideal use for them is when you have an interface that will be implemented in many places, so you don't want to put a huge burden on implementors, but you want the interface to be convenient to use from the caller's perspective as well.
So you put the "helpers" into a set of extension methods, leaving the interface itself nice and lean.
interface IZoomable
{
double ZoomLevel { get; set; }
}
public static void SetDefaultZoom(this IZoomable z)
{
z.ZoomLevel = 100;
}
Extension methods are a great way to add functionality to classes that you don't own (no source), are in the framework or that you don't want to inherit for whatever reason.
I like them, but you are right. They should be used judiciously.