How to instantiate a class in Objective-C that don't inherit from NSObject - objective-c

Given this:
Person.h:
#interface Person
{
}
- (void) sayHello;
#end
Person.m:
#import "Person.h"
#implementation Person
- (void)sayHello
{
printf("%s", "Steve");
}
#end
How do you instantiate the Person? I tried this:
Person *p = [Person new];
That doesn't work, nor this:
Person *p = [Person alloc];
[UPDATE]
I forgot to tell, I already tried inheriting from NSObject, the new and alloc works. I'm just curious if we can instantiate a class that doesn't inherit from NSObject?

You absolutely can do so. Your class simply needs to implement +alloc itself, the way that NSObject does. At base, this just means using malloc() to grab a chunk of memory big enough to fit the structure defining an instance of your class.
Reference-counted memory management would also be nice (retain/release); this is actually part of the NSObject protocol. You can adopt the protocol and implement these methods too.
For reference, you can look at the Object class, which is a root ObjC class like NSObject, that Apple provides in its open source repository for the Objective-C runtime:
#implementation Object
// Snip...
+ alloc
{
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
}
// ...
- init
{
return self;
}
// And so on...
That being said, you should think of NSObject as a integral part of the ObjC runtime. There's little if any reason to implement your own root class outside of curiosity, investigation, or experimentation (which should, however, not be discouraged at all).

You must:
Inherit from NSObject,
Do a "poor man's" class with your own mallocs, etc, or
Use Objective-C++ and create a C++ class.
Of course, neither of the other two fit into Objective-C storage management, and their call protocols, etc, are different.

There is (very likely) no good reason to not want to inherit from NSObject, but there are many good reasons to do so.
I would be curious as to your reason for why you don't want to inherit from NSObject. I would guess it stems from a lack of knowledge rather than a real need.
But even without knowing that reason: Don't do it. It's so hard to do this well in a way that it still plays nice with other Objective-C classes as to be virtually impossible.
Anyway, you're instantiating your objects in a way that hides what's really done. While in Java, you usually create instances via the default constructor method new, in Objective-C you instantiate by calling alloc on the class and then init on the instance:
Person *aPerson = [[Person alloc] init];
(It is possible to just use Person new, but I wouldn't do it because it hides what's really done from you)
You implement your class such that you inherit from NSObject and then, if necessary, write your own init method.
If you want to log to the console, use NSLog:
NSLog(#"Hello %#", #"Steven");
(#"" is a special constructor for a NSString. Strings in Objective-C are not byte arrays, but objects.)

you can't..
Alloc and new ..copy init all these methods are defined in NSObject..
You cannot also create your own since apple does not provide NSObject implementation class..so you have to inherit from NSObject or its subclass so that you can initialize your class

Related

How to allocate an NSObject subclass instance FROM an instance of its superclass?

Given a class structure such as...
#interface SuperClassView : NSView #end
#interface SubClassedView : SuperClassView #property int aProp; #end
How can one instantiate a SubClassedView from an instance of a SuperClassView?
Say a method returns an instance of the superclass SuperView....
SuperClassView *superInstance = [ViewFactory makeSuperClassView];
but I want to get an instance of the subclass SubClassedView? It is not possible to simply "cast" it...
SubClassedView *subClsInstance = (SubClassedView*)[ViewFactory makeSuperClassView];
and there is no built-in (or easily-imagined implementation of an) NSObject method like
self = [super initWithInstance:[superInstance copy]];`
Is the only way to either copy the superclass instance's desired properties to the newly instantiated subclass object, like...
SubClassedView *subClsInstance = SubClassedView.new;
for (NSString* someKey in #["frame",#"color",#"someOtherProperty])
[subClsInstance setValue:[superInstance valueForKey:someKey] forKey:someKey];
Or add (swizzle at runtime) the subclass' "additional property methods" (in this case setAProp: and aProp) to the superclass instance (and also cast it upwards)...
SubClassedView *subClsInstance = (SubClassedView*)[ViewFactory makeSuperClassView];
[subClsInstance addSwizzleMethod:#selector(setAProp:) viaSomeMagic:....];
[subClsInstance addSwizzleMethod:#selector(aProp) viaSomeMagic:....];
Hopefully this is an easy runtime trick that I simply don't know... not a sad sign that I am haplessly trying to trick ObjC into multiple-inheritance via some embarrassing anti-pattern. Either way, ideas?
EDIT: Pending #BryanChen posting his comment as an answer this is achieved easily via his suggested runtime function, or as a category on NSObject á la..
#implementation NSObject (SettingClass)
- (void)setClass:(Class)kls { if (kls) object_setClass(self, kls); } #end
What you are trying to do is pretty non-idiomatic... it feels like you are trying to do something like prototype based OOP. A couple of quick points:
Don't do the swizzle. You can't swizzle onto an instance, you swizzle onto the class definition, so if you do that you won't be adding the subclasses methods onto "an" instance of the superclass, you will be adding them onto all instances of the superclass.
Yes, if you want to do this you just need to copy the the properties you want from the super into the new instance of the subclass.
You can have a factory method in the superclass that returns a subclass, and encapsulate all the the copying in there (so, -[SuperClassView makeSubclassView] that returns SubClassedView *. That is actually relatively common, and is how many of the class clusters are implemented (though they return private subclasses that conform to the implementation of the superclass)
object_setClass is not the droid you're looking for.
Yes, it will change the class of the instance. However, it will not change the size of it. So if your SubClassView declares extra properties or instance variables that are not declared on SuperClassView, then your attempts to access them on this frankenstein instance will result in (at best) buffer overflows, (probably) corrupted data, and (at worst) your app crashing.
It sounds like you really just want to use self in your factory method:
+ (instancetype)makeView {
return [[self alloc] init];
}
Then if you call [SuperClassView makeView], you get back an instance of SuperClassView. If you call [SubClassView makeView], you get back an instance of SubClassView.
"But," you say, "how do I customize the properties of the view if it's a SubClassView?"
Just like you would with anything else: you override the method on SubClassView:
#implementation SubClassView
+ (instancetype)makeView {
SubClassView *v = [super makeView];
v.answer = 42;
return v;
}
#end
object_setClass may or may not be the "runtime trick" you are looking for. It does isa swizzle which change the class of an instance at runtime. However it does have many constrains such as that the new class cannot have extra ivars. You can check this question for more details.
I think the better way to do is that instead of making view using [ViewFactory makeSuperClassView], make it [[SuperClassView alloc] initWithSomething]. Then you can do [[SubClassView alloc] initWithSomething]
or if you really want use ViewFactory, then make it [ViewFactory makeViewOfClass:]

Exposing/Synthesizing iVar properties in Objective c

I have a class that essentially acts as a light weight wrapper class around another class. It holds that other class as an iVar. I want to be able to expose certain properties (quite a few actually) of the iVar, but to do so I have to write out each property accessor like so:
- (void) setProperty:(Class *)value{
_iVar.property = value;
}
- (Class *) property{
return _iVar.property;
}
Of course, I have to do this for every single property, which is a pain (there are about 30 of them). I would love to be able to synthesize this but I haven't been able to figure out how.
Is it possible to synthesize?
Also, I can't subclass....well, I might be able to but it's really not recommended. The iVar class is really quite heavy (it implements CoreText). I'd rather write out the methods by hand.
Ok, so here's the solution I found...ended up being pretty simple once you knew what to do. First overwrite '- (id) forwardingTargetForSelector:(SEL)aSelector' and return the iVar:
- (id) forwardingTargetForSelector:(SEL)aSelector{
return iVar;
}
When the runtime is looking for a method and cannot find one, it will call this method to see if there is another object to forward the message to. Note that this method normally returns nil and if you return nil here, your program will crash (which is the appropriate behavior).
The second part of the problem is to shush the compiler errors/warnings you'll get when you try to send a message that's not declared. This is easily done by declaring a category you don't implement.
#interface Class (iVarClassMethods)
#propoperty (strong) Class *property1;
......more properties
#end
As long as you don't put in an implementation anywhere, aka #implementation Class (category), the compiler won't complain (it'll assume that the implementation is somewhere....).
Now the only drawback I see is if you change any of the properties in the interface of the iVar Class, you need to make sure you update all other classes that use the method described above, otherwise you'll crash when another class tries to send what is now the wrong method (and the compiler won't warn you beforehand). However, this can be gotten around. You can declare protocols in a category. So instead you create a separate protocol for the iVar class and move the methods/properties you wish out of the iVar class into the protocol.
#protocol iVarClassProtocol
#propoperty (strong) Class *property1;
......more properties
#end
Add that protocol to the iVar subclass so it has those methods declared through the protocol now.
#interface iVarClass <iVarClassProtocol>
....other methods/properties you don't need forwarded
#end
Finally, simply add the protocol to the category. So instead of the aforementioned category with explicit declarations you'll have:
#interface Class (iVarClassMethods) <iVarClassProtocol>
#end
Now, if you need to change any of the to-be-fowarded properties/methods, you change them in the protocol. The compiler will then warn you when you try to send the wrong method to the forwarding class.
I think you can forward the messages to the ivar:
- (void) forwardInvocation: (NSInvocation*) invocation
{
[invocation invokeWithTarget:ivar];
}
- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector
{
NSMethodSignature *our = [super methodSignatureForSelector:selector];
NSMethodSignature *ivars = [ivar methodSignatureForSelector:selector];
return our ? our : ivars;
}
Then you have to hide or fake the type of your object, for example by casting to id, otherwise the compiler will complain that your class does not implement those methods.
Of course it would be best if you could come up with some better design that would do without such tricks.

Arguments for a copy method versus a copy constructor in Objective-C

I'm relatively new to the world of Objective-C and have a class that I've written to which I'd like to add the ability to create a copy.
Coming from Java, I know that I could either write a copy constructor or a clone method, with the latter commonly not being recommended. However, Objective-C is a different language and before I proceed I'd like to understand the arguments for a copy method versus a copy constructor in Objective-C. What is the most commonly used approach?
The recommended way to add the ability to copy objects is by implementing the NSCopying protocol.
Many foundation classes also implement NSCopying.
Refer to this answer for more information: Implementing NSCopying
Use: -(id)copyWithZone:(NSZone*)zone which is part of the NSCopying protocol
Example:
in .h:
#interface MyClass : NSObject <NSCopying>
in .m
-(id)copyWithZone:(NSZone*)zone {
MyClass *copy = [[[self class] allocWithZone: zone] init];
copy.user = self.user;
copy.password = self.password;
// etc
return copy;
}

Is a C# "constructor" the same as an Obj-C "initializer"?

I am very, very new to Obj-C, and will have a ton of questions. (I have the book "iPhone Programming, The Big Nerd Ranch Guide", but it doesn't address the differences between C# and Obj-C. Does anyone know of a doc that does address the differences?).
Anyway, my question is above...
In Objective-C, object allocation and initialization are separate operations, but it's common and a good practice to see them called in the context of the same expression:
MyClass *myInstance = [[MyClass alloc] init];
// ...
[myInstance release];
In C#, allocation and initialization happen when you use new:
MyClass myInstance = new MyClass();
The runtime allocates the instance and then calls the constructor.
So yes, the C# constructor is equivalent to the Objective-C initializer, but the usage is different.
Apart from this ... init in Objective-C is just a normal instance method, without any special semantics. You can call it at any point. In C#, constructors are very special static-like methods treated differently by the runtime and with special rules. For example, the C# compiler enforces calls to the base class constructor.
They are similar only as much as you can compare two completely different methods for creating an object. Checkout this information on the Objective-C Runtime.
The following is a very simple (but hopefully not misleading) explanation:
Objective-C
id object = [MyObject alloc]; // allocates the memory and returns a pointer. Factory-like method from NSObject (unless your class overrides it)
MyObject *myObj = [object init]; // initializes the object by calling `-(id)init`. You'll want to override this, or a similar init method for all your classes.
Usually written like this:
MyObject *myObj = [[MyObject alloc] init];
From what I know, the C# constructor allocates the memory and calls the appropriate constructor function to initialize the object.
A difference is that in C# you can't call an inherited constructor (see the bottom of the link above) but in Obj-C this will compile, but will give you wrong results.
#interface ClassA : NSObject
- (id) initWithInteger:(int)num;
#end
#interface ClassB : ClassA
- (id) init;
#end
#implementation ClassB
- (id) init
{
self = [supere initWithInteger:10];
return self;
}
// main
ClassA *a = [[ClassA alloc] initWithInteger:10]; //valid
ClassB *a = [[ClassB alloc] initWithInteger:10]; // will call init from classA, bypassing and not calling init for classB.
Just be careful with weak/dynamic typed language of Objective-C
They're similar, but not identical. Technically, a constructor fully creates and initializes an instance, while an initializer takes an already constructed instance (usually gotten through alloc) and sets the instance up so that it's ready to be used.
As for the differences between Objective-C and C#: They're two different and mostly unrelated languages. When you're learning a new language, trying to think of it as "Like this language I already know, but with these differences" can actually make it harder to learn, because there are a lot of differences and they're often subtle, so going in with assumptions from another language will confuse you. If you search around Stack Overflow, you'll find a lot of PHP programmers who start to learn a new language and immediately wonder "How do I do variable variables in this language?" It's like looking for a list of the differences between English and Chinese — you're better off not trying to treat one like the other. Keep in mind what you already know, but try not to assume any of it is the same in Objective-C.

Creating an abstract class in Objective-C

I'm originally a Java programmer who now works with Objective-C. I'd like to create an abstract class, but that doesn't appear to be possible in Objective-C. Is this possible?
If not, how close to an abstract class can I get in Objective-C?
Typically, Objective-C class are abstract by convention only—if the author documents a class as abstract, just don't use it without subclassing it. There is no compile-time enforcement that prevents instantiation of an abstract class, however. In fact, there is nothing to stop a user from providing implementations of abstract methods via a category (i.e. at runtime). You can force a user to at least override certain methods by raising an exception in those methods implementation in your abstract class:
[NSException raise:NSInternalInconsistencyException
format:#"You must override %# in a subclass", NSStringFromSelector(_cmd)];
If your method returns a value, it's a bit easier to use
#throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:#"You must override %# in a subclass", NSStringFromSelector(_cmd)]
userInfo:nil];
as then you don't need to add a return statement from the method.
If the abstract class is really an interface (i.e. has no concrete method implementations), using an Objective-C protocol is the more appropriate option.
No, there is no way to create an abstract class in Objective-C.
You can mock an abstract class - by making the methods/ selectors call doesNotRecognizeSelector: and therefore raise an exception making the class unusable.
For example:
- (id)someMethod:(SomeObject*)blah
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}
You can also do this for init.
Just riffing on #Barry Wark's answer above (and updating for iOS 4.3) and leaving this for my own reference:
#define mustOverride() #throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:#"%s must be overridden in a subclass/category", __PRETTY_FUNCTION__] userInfo:nil]
#define methodNotImplemented() mustOverride()
then in your methods you can use this
- (void) someMethod {
mustOverride(); // or methodNotImplemented(), same thing
}
Notes: Not sure if making a macro look like a C function is a good idea or not, but I'll keep it until schooled to the contrary. I think it's more correct to use NSInvalidArgumentException (rather than NSInternalInconsistencyException) since that's what the runtime system throws in response to doesNotRecognizeSelector being called (see NSObject docs).
The solution I came up with is:
Create a protocol for everything you want in your "abstract" class
Create a base class (or maybe call it abstract) that implements the protocol. For all the methods you want "abstract" implement them in the .m file, but not the .h file.
Have your child class inherit from the base class AND implement the protocol.
This way the compiler will give you a warning for any method in the protocol that isn't implemented by your child class.
It's not as succinct as in Java, but you do get the desired compiler warning.
From the Omni Group mailing list:
Objective-C doesn't have the abstract compiler construct like Java at
this time.
So all you do is define the abstract class as any other normal class
and implement methods stubs for the abstract methods that either are
empty or report non-support for selector. For example...
- (id)someMethod:(SomeObject*)blah
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}
I also do the following to prevent the initialization of the abstract
class via the default initializer.
- (id)init
{
[self doesNotRecognizeSelector:_cmd];
[self release];
return nil;
}
Instead of trying to create an abstract base class, consider using a protocol (similar to a Java interface). This allows you to define a set of methods, and then accept all objects that conform to the protocol and implement the methods. For example, I can define an Operation protocol, and then have a function like this:
- (void)performOperation:(id<Operation>)op
{
// do something with operation
}
Where op can be any object implementing the Operation protocol.
If you need your abstract base class to do more than simply define methods, you can create a regular Objective-C class and prevent it from being instantiated. Just override the - (id)init function and make it return nil or assert(false). It's not a very clean solution, but since Objective-C is fully dynamic, there's really no direct equivalent to an abstract base class.
This thread is kind of old, and most of what I want to share is already here.
However, my favorite method is not mentioned, and AFAIK there’s no native support in the current Clang, so here I go…
First, and foremost (as others have pointed out already) abstract classes are something very uncommon in Objective-C — we usually use composition (sometimes through delegation) instead. This is probably the reason why such a feature doesn’t already exist in the language/compiler — apart from #dynamic properties, which IIRC have been added in ObjC 2.0 accompanying the introduction of CoreData.
But given that (after careful assessment of your situation!) you have come to the conclusion that delegation (or composition in general) isn’t well suited to solving your problem, here’s how I do it:
Implement every abstract method in the base class.
Make that implementation [self doesNotRecognizeSelector:_cmd];…
…followed by __builtin_unreachable(); to silence the warning you’ll get for non-void methods, telling you “control reached end of non-void function without a return”.
Either combine steps 2. and 3. in a macro, or annotate -[NSObject doesNotRecognizeSelector:] using __attribute__((__noreturn__)) in a category without implementation so as not to replace the original implementation of that method, and include the header for that category in your project’s PCH.
I personally prefer the macro version as that allows me to reduce the boilerplate as much as possible.
Here it is:
// Definition:
#define D12_ABSTRACT_METHOD {\
[self doesNotRecognizeSelector:_cmd]; \
__builtin_unreachable(); \
}
// Usage (assuming we were Apple, implementing the abstract base class NSString):
#implementation NSString
#pragma mark - Abstract Primitives
- (unichar)characterAtIndex:(NSUInteger)index D12_ABSTRACT_METHOD
- (NSUInteger)length D12_ABSTRACT_METHOD
- (void)getCharacters:(unichar *)buffer range:(NSRange)aRange D12_ABSTRACT_METHOD
#pragma mark - Concrete Methods
- (NSString *)substringWithRange:(NSRange)aRange
{
if (aRange.location + aRange.length >= [self length])
[NSException raise:NSInvalidArgumentException format:#"Range %# exceeds the length of %# (%lu)", NSStringFromRange(aRange), [super description], (unsigned long)[self length]];
unichar *buffer = (unichar *)malloc(aRange.length * sizeof(unichar));
[self getCharacters:buffer range:aRange];
return [[[NSString alloc] initWithCharactersNoCopy:buffer length:aRange.length freeWhenDone:YES] autorelease];
}
// and so forth…
#end
As you can see, the macro provides the full implementation of the abstract methods, reducing the necessary amount of boilerplate to an absolute minimum.
An even better option would be to lobby the Clang team to providing a compiler attribute for this case, via feature requests. (Better, because this would also enable compile-time diagnostics for those scenarios where you subclass e.g. NSIncrementalStore.)
Why I Choose This Method
It get’s the job done efficiently, and somewhat conveniently.
It’s fairly easy to understand. (Okay, that __builtin_unreachable() may surprise people, but it’s easy enough to understand, too.)
It cannot be stripped in release builds without generating other compiler warnings, or errors — unlike an approach that’s based on one of the assertion macros.
That last point needs some explanation, I guess:
Some (most?) people strip assertions in release builds. (I disagree with that habit, but that’s another story…) Failing to implement a required method — however — is bad, terrible, wrong, and basically the end of the universe for your program. Your program cannot work correctly in this regard because it is undefined, and undefined behavior is the worst thing ever. Hence, being able to strip those diagnostics without generating new diagnostics would be completely unacceptable.
It’s bad enough that you cannot obtain proper compile-time diagnostics for such programmer errors, and have to resort to at-run-time discovery for these, but if you can plaster over it in release builds, why try having an abstract class in the first place?
Using #property and #dynamic could also work. If you declare a dynamic property and don't give a matching method implementation, everything will still compile without warnings, and you'll get an unrecognized selector error at runtime if you try to access it. This essentially the same thing as calling [self doesNotRecognizeSelector:_cmd], but with far less typing.
In Xcode (using clang etc) I like to use __attribute__((unavailable(...))) to tag the abstract classes so you get an error/warning if you try and use it.
It provides some protection against accidentally using the method.
Example
In the base class #interface tag the "abstract" methods:
- (void)myAbstractMethod:(id)param1 __attribute__((unavailable("You should always override this")));
Taking this one-step further, I create a macro:
#define UnavailableMacro(msg) __attribute__((unavailable(msg)))
This lets you do this:
- (void)myAbstractMethod:(id)param1 UnavailableMacro(#"You should always override this");
Like I said, this is not real compiler protection but it's about as good as your going to get in a language that doesn't support abstract methods.
The answer to the question is scattered around in the comments under the already given answers. So, I am just summarising and simplifying here.
Option1: Protocols
If you want to create an abstract class with no implementation use 'Protocols'. The classes inheriting a protocol are obliged to implement the methods in the protocol.
#protocol ProtocolName
// list of methods and properties
#end
Option2: Template Method Pattern
If you want to create an abstract class with partial implementation like "Template Method Pattern" then this is the solution.
Objective-C - Template methods pattern?
Another alternative
Just check the class in the Abstract class and Assert or Exception, whatever you fancy.
#implementation Orange
- (instancetype)init
{
self = [super init];
NSAssert([self class] != [Orange class], #"This is an abstract class");
if (self) {
}
return self;
}
#end
This removes the necessity to override init
(more of a related suggestion)
I wanted to have a way of letting the programmer know "do not call from child" and to override completely (in my case still offer some default functionality on behalf of the parent when not extended):
typedef void override_void;
typedef id override_id;
#implementation myBaseClass
// some limited default behavior (undesired by subclasses)
- (override_void) doSomething;
- (override_id) makeSomeObject;
// some internally required default behavior
- (void) doesSomethingImportant;
#end
The advantage is that the programmer will SEE the "override" in the declaration and will know they should not be calling [super ..].
Granted, it is ugly having to define individual return types for this, but it serves as a good enough visual hint and you can easily not use the "override_" part in a subclass definition.
Of course a class can still have a default implementation when an extension is optional. But like the other answers say, implement a run-time exception when appropriate, like for abstract (virtual) classes.
It would be nice to have built in compiler hints like this one, even hints for when it is best to pre/post call the super's implement, instead of having to dig through comments/documentation or... assume.
If you are used to the compiler catching abstract instantiation violations in other languages, then the Objective-C behavior is disappointing.
As a late binding language it is clear that Objective-C cannot make static decisions on whether a class truly is abstract or not (you might be adding functions at runtime...), but for typical use cases this seems like a shortcoming. I would prefer the compiler flat-out prevented instantiations of abstract classes instead of throwing an error at runtime.
Here is a pattern we are using to get this type of static checking using a couple of techniques to hide initializers:
//
// Base.h
#define UNAVAILABLE __attribute__((unavailable("Default initializer not available.")));
#protocol MyProtocol <NSObject>
-(void) dependentFunction;
#end
#interface Base : NSObject {
#protected
__weak id<MyProtocol> _protocolHelper; // Weak to prevent retain cycles!
}
- (instancetype) init UNAVAILABLE; // Prevent the user from calling this
- (void) doStuffUsingDependentFunction;
#end
//
// Base.m
#import "Base.h"
// We know that Base has a hidden initializer method.
// Declare it here for readability.
#interface Base (Private)
- (instancetype)initFromDerived;
#end
#implementation Base
- (instancetype)initFromDerived {
// It is unlikely that this becomes incorrect, but assert
// just in case.
NSAssert(![self isMemberOfClass:[Base class]],
#"To be called only from derived classes!");
self = [super init];
return self;
}
- (void) doStuffUsingDependentFunction {
[_protocolHelper dependentFunction]; // Use it
}
#end
//
// Derived.h
#import "Base.h"
#interface Derived : Base
-(instancetype) initDerived; // We cannot use init here :(
#end
//
// Derived.m
#import "Derived.h"
// We know that Base has a hidden initializer method.
// Declare it here.
#interface Base (Private)
- (instancetype) initFromDerived;
#end
// Privately inherit protocol
#interface Derived () <MyProtocol>
#end
#implementation Derived
-(instancetype) initDerived {
self= [super initFromDerived];
if (self) {
self->_protocolHelper= self;
}
return self;
}
// Implement the missing function
-(void)dependentFunction {
}
#end
Probably this kind of situations should only happen at development time, so this might work:
- (id)myMethodWithVar:(id)var {
NSAssert(NO, #"You most override myMethodWithVar:");
return nil;
}
You can use a method proposed by #Yar (with some modification):
#define mustOverride() #throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:#"%s must be overridden in a subclass/category", __PRETTY_FUNCTION__] userInfo:nil]
#define setMustOverride() NSLog(#"%# - method not implemented", NSStringFromClass([self class])); mustOverride()
Here you will get a message like:
<Date> ProjectName[7921:1967092] <Class where method not implemented> - method not implemented
<Date> ProjectName[7921:1967092] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[<Base class (if inherited or same if not> <Method name>] must be overridden in a subclass/category'
Or assertion:
NSAssert(![self respondsToSelector:#selector(<MethodName>)], #"Not implemented");
In this case you will get:
<Date> ProjectName[7926:1967491] *** Assertion failure in -[<Class Name> <Method name>], /Users/kirill/Documents/Projects/root/<ProjectName> Services/Classes/ViewControllers/YourClass:53
Also you can use protocols and other solutions - but this is one of the simplest ones.
Cocoa doesn’t provide anything called abstract. We can create a class abstract which gets checked only at runtime, and at compile time this is not checked.
I usually just disable the init method in a class that I want to abstract:
- (instancetype)__unavailable init; // This is an abstract class.
This will generate an error at compile time whenever you call init on that class. I then use class methods for everything else.
Objective-C has no built-in way for declaring abstract classes.
Changing a little what #redfood suggested by applying #dotToString's comment, you actually have the solution adopted by Instagram's IGListKit.
Create a protocol for all the methods that make no sense to be defined in the base (abstract) class i.e. they need specific implementations in the children.
Create a base (abstract) class that does not implement this protocol. You can add to this class any other methods that make sense to have a common implementation.
Everywhere in your project, if a child from AbstractClass must be input to or output by some method, type it as AbstractClass<Protocol> instead.
Because AbstractClass does not implement Protocol, the only way to have an AbstractClass<Protocol> instance is by subclassing. As AbstractClass alone can't be used anywhere in the project, it becomes abstract.
Of course, this doesn't prevent unadvised developers from adding new methods referring simply to AbstractClass, which would end up allowing an instance of the (not anymore) abstract class.
Real world example: IGListKit has a base class IGListSectionController which doesn't implement the protocol IGListSectionType, however every method that requires an instance of that class, actually asks for the type IGListSectionController<IGListSectionType>. Therefore there's no way to use an object of type IGListSectionController for anything useful in their framework.
In fact, Objective-C doesn't have abstract classes, but you can use Protocols to achieve the same effect. Here is the sample:
CustomProtocol.h
#import <Foundation/Foundation.h>
#protocol CustomProtocol <NSObject>
#required
- (void)methodA;
#optional
- (void)methodB;
#end
TestProtocol.h
#import <Foundation/Foundation.h>
#import "CustomProtocol.h"
#interface TestProtocol : NSObject <CustomProtocol>
#end
TestProtocol.m
#import "TestProtocol.h"
#implementation TestProtocol
- (void)methodA
{
NSLog(#"methodA...");
}
- (void)methodB
{
NSLog(#"methodB...");
}
#end
A simple example of creating an abstract class
// Declare a protocol
#protocol AbcProtocol <NSObject>
-(void)fnOne;
-(void)fnTwo;
#optional
-(void)fnThree;
#end
// Abstract class
#interface AbstractAbc : NSObject<AbcProtocol>
#end
#implementation AbstractAbc
-(id)init{
self = [super init];
if (self) {
}
return self;
}
-(void)fnOne{
// Code
}
-(void)fnTwo{
// Code
}
#end
// Implementation class
#interface ImpAbc : AbstractAbc
#end
#implementation ImpAbc
-(id)init{
self = [super init];
if (self) {
}
return self;
}
// You may override it
-(void)fnOne{
// Code
}
// You may override it
-(void)fnTwo{
// Code
}
-(void)fnThree{
// Code
}
#end
Can't you just create a delegate?
A delegate is like an abstract base class in the sense that you say what functions need to be defined, but you don't actually define them.
Then whenever you implement your delegate (i.e abstract class) you are warned by the compiler of what optional and mandatory functions you need to define behavior for.
This sounds like an abstract base class to me.