How to create a protocol in objective-C - objective-c

I want to create a Utils file, to have some functions and use them in some classes, but I'm not sure of how to do it.
I have:
Utils.h
#import <Foundation/Foundation.h>
#protocol Utils
#optional
-(NSString*)colorToHex:(UIColor*)color;
#end
#interface Utils : NSObject
#end
Utils.m
#import "Utils.h"
#implementation Utils
-(NSString*)colorToHex:(UIColor*)color{
return #"Working";
}
#end
mainClass.h (snippet)
#interface StyleTableViewController : UITableViewController <Utils>
mainClass.m (the call)
NSString *myString = [self colorToHex:color];
NSLog(#"%#",myString);
And it crashes when it calls the function. What should I do?
Thanks

When you state that your class conforms to a protocol (by adding ) you tell the compiler that this class implements all the methods defined in the protocol.
A Protocol is not a class - it's just a list of methods. So in your code, you had a protocol call Utils, and a class called Utils. You conformed to the protocol, but did not implement the methods, which is why the program crashed when you tried to call colorToHex.
What you need to do in your case is create a Util object in your StyleTableViewController and use it to call the colorToHex method, or make the colorToHex method a class method and call it from the Util class when needed. Another option would be to make StyleTableViewController a subclass of Utils, but I doubt this will be a good design here.

Another option would be to add a category Utils to UIColor. Not exactly what you asked for but it solves your problem more elegantly than using a protocol.

Related

Calling a method defined in a protocol on a class included with forward declaration

Is there a way to tell the compiler that a non-imported class (i.e. forward declaration) adheres to a protocol?
In the example below I want to call a method foo on the class ForwardClass. The class adheres to the MyProtocol protocol, but the compiler won't know that since forward declaration is used.
#protocol MyProtocol <NSObject>
+ (void) foo;
#end
#class ForwardClass; // <-- Forward declaration
#implementation MyClass
- (void) bar
{
[ForwardClass foo]; // <-- This doesn't work!
}
What I was hoping for was to either apply the protocol while declaring the class like so:
#class ForwardClass <MyProtocol>
or to somehow use the protocol while calling the method like so:
[ForwardClass<MyProtocol> foo];
This is not really a big issue since I could just import the class straight away, but it would be nice if it worked since I would only have to import the protocol, and not the whole class.
No. Forward declarations are for situations where you need to know the the class type but don't need to know about its specific implementation (properties and methods for example). In your case you do care about the methods it implements so you need to bring in the header for for ForwardClass.
You could do
Class x = NSClassFromString(#"ForwardClass");
[x foo];
but it is not as pretty

Declaring method prototypes in header and implementation

I am learning object orientated programming from the online Stanford courses there is a part I am unsure of regarding declarations. I thought that you must always declare the prototype in the header and then write the code in the implementation file, but the professor wrote a method in the implementation without a declaration prototype in the header file, how come?
Also, may someone please clear the difference between private and public and if the method without a prototype is public or private? The method without a prototype is not from a super class.
That is a perfectly legal way to declare methods that are not to be used outside the class implementation itself.
The compiler will find methods in the implementation file as long as they precede the method in which they are used. However that will not always be the case, as the new LLVM compiler allows methods to be declared in any order and referenced from a given file.
There are a couple of different styles for declaring methods inside an implementation file:
//In the Header File, MyClass.h
#interface MyClass : NSObject
#end
//in the implementation file, MyClass.m
//Method Decls inside a Private Category
#interface MyClass (_Private)
- (void)doSomething;
#end
//As a class extension (new to LLVM compiler)
#interface MyClass ()
- (void)doSomething;
#end
#implementation MyClass
//You can also simply implement a method with no formal "forward" declaration
//in this case you must declare the method before you use it, unless you're using the
//latest LLVM Compiler (See the WWDC Session on Modern Objective C)
- (void)doSomething {
}
- (void)foo {
[self doSomething];
}
#end
If you write the method in you header file it is public and accessible for other classes / objects. If you do not declare it in the header file the method is a private method meaning that you can access it internally in you class but no other class can use this method.

Cocoa Singletons and Protocols

I want to define a protocol and create an easy, standard way to grab a 'default', shared implementation of said protocol - singleton style. Cocoa adhere's to the following pattern:
[NSUserDefaults standardUserDefaults]
[NSNotificationCenter defaultCenter]
but in both cases, they have #interfaces at the bottom of the object hierarchy. I'm struggling with how to do this using #protocols. I can obviously create a class that has empty or simple method implementations - but in reality, what I want is a #protocol at the bottom of the hierarchy. I've tried something like:
#protocol ConfigurationManager <NSObject>
//...
#interface ConfigurationManagerFactory : NSObject
+ (id<ConfigurationManager>)sharedConfiguration;
#end
// ...
id<ConfigurationManger> config = [ConfigurationManagerFactory sharedConfiguration];
[config ...];
and it works - but I'm always having to explain how to use this and why I did it this way. Is there a way to conform to Cocoa's syntax (calling convention) while still leveraging the value of #protocols?
As an aside, is there a reason why I wouldn't want to use #protocols like this? The implementing #interface can still leverage categories and alternate implementations, etc - just like how instantiating an NSString usually leaves you with a class extending NSString.
Here's an idea: create your protocol and a class with the same name with a factory method that returns you the default implementation of the protocol:
#protocol ConfigurationManager <NSObject> ...
#interface ConfigurationManager : NSObject <ConfigurationManager>
+(ConfigurationManager *) defaultConfigurationManager;
...
Other specialized implementations can then inherit from your base class.
The whole point of a protocol is that it specifies an interface without providing an implementation. If you want a default implementation, provide a class that implements your protocol, much as the NSObject class implements the NSObject protocol. Then clients can either subclass the class that you provide, or instantiate the class you provide and use the resulting object's implementation, as with your config object.

Does Objective-C have something like C++ virtual functions?

In objective-c it is possible to add a #dynamic to a property.
Is this also possible for normal instance methods?
EDIT
I think i wasn't clear enough.
I want to do the following:
#interface MyClass
#property (retain) NSObject *somePropertyObject;
- (void) myMethod;
#end
#implementation MyClass
#dynamic somePropertyObject;
//Make myMethod dynamic. I do not want to implement it. Like C++ Virtual
#end
If you mean "How can I declare a method, but not provide a definition which I will subsequently provide at runtime?" Then it's easy, just use a category. Like this:
#interface MyObject : NSObject
// Methods I'll define
- (void)doFoo;
#end
#interface MyObject (DynamicallyProvidedMethods)
// Methods I won't
- (void)myDynamicMethod;
#end
#implementation MyObject
// Methods I'll define
- (void)doFoo
{
}
#end
The compiler will not complain, however if you call -myDynamicMethod at runtime, unless you have provided an implementation for it somehow, it will crash with "unrecognized selector." You can, of course, test for that at runtime by calling respondsToSelector:.
Relatedly, if you're looking to do a near-equivalent of a base class pure virtual method, I would recommend providing an empty implementation that asserts when called if it has not been overridden by a subclass. You can do that like so:
NSAssert((class_getInstanceMethod([self class], _cmd) == class_getInstanceMethod([MyObject class], _cmd)),
#"Subclass of %# must override -%#",
NSStringFromClass([MyObject class]),
NSStringFromSelector(_cmd));
// ...where overridesSelector:ofBaseClass: looks like:
//
// return ;
Of course, that won't alert you to problems at compile time, but it's better than nothing.
HTH
I think you might be asking how to declare a method that will be implemented some time later somewhere else.
The Objective-C way to do that is to use Protocols.
You declare a protocol like this, usually in a header file
#protocol MyProtocol <NSObject> {
#optional
- (void)optionalMethod;
#required
- (void)requiredMethod;
}
#end
This declares two methods, one which is optional and one is required. To use this protocol you declare the conformance when declaring the class that will implement the protocol
#interface MyConformingClass : NSObject <MyProtocol> {
}
// you don't have to redeclare methods that are declared in the protocol
#end
This new class is checked at compile time for the implementation of requiredMethod so it has to implement it, but it can choose whether or not to implement the optionalMethod
Now, any class that requires instances of objects to conform to the protocol can declare this, for example, in the interface
#interface RequiringClass : NSObject {
MyConformingClass <MyProtocol> *conformingClassObject;
}
…
#end
Again, this is checked at compile time
To make sure that the conforming class implement the #optional methods, we can use this handy structure
if [conformingClassObject respondsToSelector:#selector(optionalMethod)] {
[conformingClassObject optionalMethod];
} else {
// Do something here because the optional method isn't provided
}
Examples of this are all over Cocoa - it's a class can provide a list of actions that it would like to farm out to it's delegate, the delegate adopts the protocol and provides the implementations of those delegate methods. The calling object can then check if this delegate responds to those methods at runtime as I've described above, and call those methods to perform actions, or provide information where ever it needs to.
This is used quite a lot in Objective-C, where classes provide a list of methods that they would like some other class to perform, unlike virtual functions, where a class declares functions it wants subclasses to provide implementations for. Particularly as Composition is favoured over inheritance in the language. Rather than create a subclass to provide an implementation, you just create another class that can do the same thing, and add a reference to that in the class instead.
No.
#dynamic is just an instruction to the compiler that says: "Don't bother generating accessors for this property, I'm going to provide my own."
Using #dynamic with other methods wouldn't be helpful because the compiler doesn't generate any methods other than accessors for you, and of course you're supplying the other methods anyway.
What are you trying to accomplish?

Category usage in Objective-C

I'm seeing some code I've inherited that looks like the following:
#interface SomeClass (private)
This is within SomeClass.m, the implementation file. There is an accompanying header file which doesn't suggest that the class is using a category. Is (private) in this case just a poor name given to a category for SomeClass? And I'm assuming it's perfectly legitimate to specify categories such as these in an implementation?
It isn't the name "private" that makes it private; the methods are private because they are in a category declared within the implementation file.
There are three uses of a category, each of which add methods to a class (note: methods only, not iVars)
Extending an existing Cocoa class
This lets you add your own methods to an existing class.
For example, if you want to extend NSString to apply special capitalization, you could create a new class called, say NSString+Capitals. in the NSString+Capitals.h you would have:
#interface NSString (Capitals)
-(NSString *)alternateCaps:(NSString *)aString;
#end
and in NSString+Capitals.m you would implement the method
#implementation NSString (Capitals)
-(NSString *)alternateCaps:(NSString *)aString
{
// Implementation
}
Private methods on a class
This is the same as above, except that the extra methods are declared and defined in the implementation file (.m) Usually a way of having private methods - because they are not in the .h file (which is the one #imported by other classes) they are simply not visible. In this case, the implementation of the methods are done in their own implementation block. e.g
// someClass.m
#interface someClass (extension)
-(void)extend;
#end
#implementation someClass
// all the methods declared in the .h file and any superclass
// overrides in this block
#end
#implementation someClass (extension)
-(void)extend {
// implement private method here;
}
Class Extension (New for 10.5 Leopard)
A simpler way of having private methods. In this special case, the category name is empty and the private methods are implemented in the same block as all the other class methods.
// someClass.m
#interface someClass ()
-(void)extend;
#end
#implementation someClass
// all the methods declared in the .h file and any superclass
// overrides in this block
// Implement private methods in this block as well.
-(void)extend {
// implement private method here;
}
#end
Here's a link to the Apple docs on Categories and extensions.
"Private" is just a name that suggests the methods are not public and are used for the internal implementation of the class, but there's nothing in the declaration of the category that enforces that.
Also, methods defined in a category are added to the class definition at runtime, so the accompanying header file need not declare that it is using a category -- it gets "used" automatically.
I use that to give me somewhere to declare (and thus document, as well as shut the compiler up about) helper methods which don't need to be in the public interface. Then the "consumers" of the class are (tacitly, given that there's nothing stopping them other than good manners) restricted to using methods defined in the header file.