This question already has answers here:
Defining an Objective-C Class without a base Class - Compiler Warning
(3 answers)
Closed 8 years ago.
Is it possible to create a class in Objective-C without a superclass.
If I create something like
#interface Samp
#end
I get the error message: "Class Samp defined without specifying a base class".
How come NSProxy compiles?
The pedantic answer is yes, you can. You just have to make your class a root class, which you can do by using the compiler attribute objc_root_class.
__attribute__((objc_root_class))
#interface Samp
#end
or using the convenience macro NS_ROOT_CLASS
NS_ROOT_CLASS
#interface Samp
#end
This is the same thing NSProxy does.
NS_ROOT_CLASS
#interface NSProxy <NSObject> {
Class isa;
}
Now, unless you're doing something really specific and out of the schemes, I don't see why you would want to do that.
Juts make your class to inherit from an existing root class, like NSObject (the most common) or NSProxy.
How come NSProxy compiles?
NSProxy class is special - it is one of Cocoa's two public root classes (NSObject is the other one). If you must define your own root class, this answer tells you how to do it. However, in practice there should be no reason to implement your own root class.
Related
I'm wondering if it is possible, in a certain subclass, to "recognise" methods declared in it's superclass as implementations of methods declared in a protocol the subclass adheres to, given that they have the same signatures.
It kind of gets hard to even formulate this, that's why any searches I made turned out fruitless so far.
But let me make the case with an example for better understanding.
Protocol:
#protocol TheProtocol <NSObject>
- (void)theProtocolMethod;
#end
Superclass:
// Superclass does not adhere to TheProtocol
#interface TheSuperClass : NSObject
- (void)theProtocolMethod;
#end
#implementation TheSuperClass
- (void)theProtocolMethod
{
// stuff
}
#end
Subclass:
// SubClass adheres to TheProtocol but does not implement it's methods
// since they are implemented in the class it is subclassing. Is this OK?
#interface TheSubClass : TheSuperClass <TheProtocol>
#end
#implementation TheSubClass
#end
Is this anywhere close to being "OK"?
What about the case TheSubClass was in fact a category of TheSuperClass (declaring adherence to TheProtocol) and not a subclass?
A bit more context:
It's a scenario involving Core Data. I need to publish an accessor defined in an Entity Class, in a Protocol that will be used in a separate Framework for developing plugins for my app. The Protocol itself is fully implemented by a Category of the Core Data Entity Class, except for said accessor which is implemented in the Entity Class itself, hence my question.
In absolute terms, this is perfectly legal. Calling -theProtocolMethod on an instance of TheSubClass would indeed invoke TheSuperClass implementation if TheSubClass itself doesn't implement it. You could even call [super theProtocolMethod] in your subclass implementation, if you wanted.
If TheSubClass was a category on TheSuperClass, the superclass implementation would still be called. However, implementing -theProtocolMethod in the category would replace the super class implementation, so you have to be careful here.
Subjectively, in code-design terms, it's maybe a little odd. You essentially have two separate declarations of the same method to manage, which could potentially cause problems if you tried to refactor. I'm guessing the superclass in your case is a library class that you cannot change. Otherwise, I can't see why TheSuperClass shouldn't just conform to the protocol, rather than declare the method separately.
In theory you're saying the superclass is already compliant with the protocol.
If the compiler complains, you can implement wrapper methods in your subclass that simply call super and return any return value from the call to super.
This question already has answers here:
Overriding #property declarations in Objective-C
(2 answers)
Closed 9 years ago.
I am designing a abstract base class for a model, where one property of the base class is currently id. I'd like the concrete classes to define what this "content" property type is. Is it safe to redefine the property with a specific type for compiler checking?
Base class .h:
#interface Foo : NSObject
...
#property (nonatomic, strong) id content;
#end
Concrete class .h:
#interface TextFoo : Foo
...
#property (nonatomic, strong) NSString *content;
#end
Concrete class .m now requires a #synthesize for NSString *content. Is this override safe to do, or are there unintended side effects? At some top level controller I will be using introspection for a collection of Foos, so I'm really only looking for compiler checking on concrete classes.
Edit: Just to add some additional information, this does actually work (Xcode 5.0.2) with no warnings or errors from the compiler. The abstract base class can even assign an arbitrary object in a setter and the subclass setter/getter still works.
To be very honest some (or I should say many) programmers would consider this a poor architecture design. You can do this but should not be doing this.
As far as the "safety" is considered, that is solely your responsibility now with this approach as compiler won't back you up here (thanks to dynamic nature of Objective-C). Your code may become completely safe if you keep in mind that content is no more an id type.
There might arise a situation where you assign content of base class to let's say NSDictionary object (which is pretty much valid) and somehow (if you are drunk and coding) you end up assigning this value to child's content (again thanks to dynamic nature of Objective-C, its pretty much valid). So now in this case you are not safe and your app might crash somewhere. So the moral of the story is I am not saying No to Drunken Coding, but I am saying no to poor architecture.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Conforming protocol privately
A class of mine tries to register itself as the delegate to a NSXMLParser object that it creates. However, I don't think I want my class to publicly disclose that it implements the NSXMLParserDelegate protocol, since that NSXMLParser object is a private variable used only from within the class.
Am I right to avoid disclosing the protocol, and if so, how do I implement the protocol without making it public that the class does so?
Try putting this in your .m file:
#interface MyClass (Private) <NSXMLParser>
#end
The specific category name (Private) doesn't matter – in fact you can use an empty set of parentheses (see below) – but I think this should require you to implement the required methods and tell the compiler that your class implements the protocol, at least in that file.
If that doesn't work, try simply removing <NSXMLParser> from your .h file, and casting self to id<NSXMLParser> if necessary, when setting the parser's delegate.
I would like a pattern for a nested private class in Objective C.
Requirements are:
class will not be visible/accessible to other classes.
class can execute methods (i.e., not a C struct)
containing class members are visible/accessible to the nested class
Considering the comments, I am simplifying the requirements:
inner class may be accessible to other classes, but not visible (similar to using a category to hide private methods).
inner class does not have to be nested
Is it still not possible?
Objective-C has no notion of private classes or private instance variables in a formal declarative fashion.
Instead, visibility in Objective-C is entirely controlled by where you declare something. If it is in a header file, it can be imported by something else. If it is declared in an implementation file, it cannot (reasonably) be imported and, therefore, is effectively private to that compilation unit.
And by "it", I mean pretty much anything that can be declared; class, global, etc...
I.e. if you stick an #interface/#implementation pair for a class in a .m file, that class is effectively private to that compilation unit. Of course, without namespaces, make sure that class is uniquely named.
Consider this:
Foo.h:
#interface Foo: NSObject
... public interface
#end
Foo.m:
#interface __FooSupportClass: NSObject
... interface here ...
#end
#implementation __FooSupportClass
#end
#interface Foo()
#property(retain) __FooSupportClass *__fooSupport;
#end
#implementation Foo
#synthesize __fooSupport = fooSupport__;
... etc ...
#end
That gives you a private-by-visibility support class only available in your implementation with an instance variable and setter/getter methods on your class that are not visible outside the compilation unit either.
(Note that Objective-C has "instance variables", not "member variables". They are similar, but you'll be better off using the vocabulary of the language.)
Well you can have "semi-hidden" private methods. You can include an interface file that provides extension methods that is in the implementation file and then just implement the methods declared in there. I was curious about this before and asked a similar question.
Proper Objective-C Helper "Wannabe" Private methods?
In Objective-C, I can add methods to existing classes with a category, e.g.
#interface NSString (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
#end
Is it also possible to do this with protocols, i.e. if there was a NSString protocol, something like:
#interface <NSString> (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
#end
I want to do this since I have several extensions to NSObject (the class), using only public NSObject methods, and I want those extensions also to work with objects implementing the protocol .
To give a further example, what if I want to write a method logDescription that prints an object's description to the log:
- (void) logDescription {
NSLog(#"%#", [self description]);
}
I can of course add this method to NSObject, but there are other classes that do not inherit from NSObject, where I'd also like to have this method, e.g. NSProxy. Since the method only uses public members of protocol , it would be best to add it to the protocol.
Edit: Java 8 now has this with "virtual extension methods" in interfaces: http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf. This is exactly what I would like to do in Objective-C. I did not see this question earning this much attention...
Regards,
Jochen
Short answer: No.
Long answer: how would this work? Imagine you could add methods to existing protocols? How would this work? Imagine we wanted to add another method to NSCoding, say -(NSArray *) codingKeys; This method is a required method that returns an array of the keys used to encoding the object.
The problem is that there are existing classes (like, say NSString) that already implement NSCoding, but don't implement our codingKeys method. What should happen? How would the pre-compiled framework know what to do when this required message gets sent to a class that does not implement it?
You could say "we can add the definition of this method via a category" or "we could say that any methods added via these protocol categories are explicitly optional". Yes, you could do this and theoretically get around the problem I've described above. But if you're going to do that, you might as well just make it a category in the first place, and then check to make sure the class respondsToSelector: before invoking the method.
While it's true that you can't define categories for protocols (and wouldn't want to, because you don't know anything about the existing object), you can define categories in such a way that the code only applies to an object of the given type that has the desired protocol (sort of like C++'s partial template specialization).
The main use for something like this is when you wish to define a category that depends on a customized version of a class. (Imagine that I have UIViewController subclasses that conform to the Foo protocol, meaning they have the foo property, my category code may have need of the foo property, but I can't apply it to the Foo protocol, and if I simply apply it to UIViewController, the code won't compile by default, and forcing it to compile means someone doing introspection, or just screwing up, might call your code which depends on the protocol. A hybrid approach could work like this:
#protocol Foo
- (void)fooMethod
#property (retain) NSString *foo;
#end
#implementation UIViewController (FooCategory)
- (void)fooMethod {
if (![self conformsToProtocol:#protocol(Foo)]) {
return;
}
UIViewController<Foo> *me = (UIViewController<Foo>*) self;
// For the rest of the method, use "me" instead of "self"
NSLog(#"My foo property is \"%#\"", me.foo);
}
#end
With the hybrid approach, you can write the code only once (per class that is supposed to implement the protocol) and be sure that it won't affect instances of the class that don't conform to the protocol.
The downside is that property synthesis/definition still has to happen in the individual subclasses.
extObjC has the NEATEST stuff you can do with Protocols / Categories... first off is #concreteprotocol...
Defines a "concrete protocol," which can provide default implementations of methods within protocol.
An #protocol block should exist in a header file, and a corresponding #concreteprotocol block in an implementation file.
Any object that declares itself to conform to this protocol will receive its method implementations, but only if no method by the same name already exists.
MyProtocol.h
#protocol MyProtocol
#required - (void)someRequiredMethod;
#optional - (void)someOptionalMethod;
#concrete - (BOOL)isConcrete;
MyProtocol.m
#concreteprotocol(MyProtocol) - (BOOL)isConcrete { return YES; } ...
so declaring an object MyDumbObject : NSObject <MyProtocol> will automatically return YES to isConcrete.
Also, they have pcategoryinterface(PROTOCOL,CATEGORY) which "defines the interface for a category named CATEGORY on a protocol PROTOCOL". Protocol categories contain methods that are automatically applied to any class that declares itself to conform to PROTOCOL." There is an accompanying macro you also have to use in your implementation file. See the docs.
Last, but NOT least / not directly related to #protocols is
synthesizeAssociation(CLASS, PROPERTY), which "synthesizes a property for a class using associated objects. This is primarily useful for adding properties to a class within a category. PROPERTY must have been declared with #property in the interface of the specified class (or a category upon it), and must be of object type."
So many of the tools in this library open (way-up) the things you can do with ObjC... from multiple inheritance... to well, your imagination is the limit.
It isn't really meaningful to do so since a protocol can't actually implement the method. A protocol is a way of declaring that you support some methods. Adding a method to this list outside the protocol means that all "conforming" classes accidentally declare the new method even though they don't implement it. If some class implemented the NSObject protocol but did not descend from NSObject, and then you added a method to the protocol, that would break the class's conformance.
You can, however, create a new protocol that includes the old one with a declaration like #protocol SpecialObject <NSObject>.
I think you may be mixing up terms here and there. Extensions, Categories, Protocols, Interfaces and Classes are all different things in Objective-C. In The Objective-C 2.0 Language Apple describes the differences very well, including the benefits and drawbacks to using categories and extensions.
If you think about it, what is a "Category" or "Extension" in the conceptual sense? It's a way of adding functionality to a Class. In Objective-C, protocols are designed to have no implementation. Therefore, how would you add or extend the implementation of something that doesn't have implementation to begin with?
if you're already writing a category, why not just add in the protocol definition in the header right after the category definition?
i.e.
#interface NSString (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
#end
#protocol MyExtendedProtocolName <NSString>
//Method declarations go here
#end
this way any class that imports the category header will also get the protocol definition, and you can add it into your class..
#interface MyClass <OriginalProtocol,MyExtendedProtocolName>
also, be careful when subclassing NSString, it's a cluster and you may not always get the behaviour you're expecting.
Adam Sharp posted a solution that worked for me.
It involves 3 steps:
Defining the methods you want to add as #optional on a protocol.
Making the objects you want to extend conform to that protocol.
Copying those methods into those objects at runtime.
Check out the link for the full details.