What is the equivalent concept of interface in java in objective C. I want to create a interface and define some common variables and methods which will be shared by many classes inheriting from my interface. When any class outside want to use a child class it will get a reference object of my interface which will point to correct child class.
How to achieve this in Objective C?
An Objective C equivalent of Java interfaces is called "protocol".
A small intro can also be found here, and if you want a full reference, it's at Apple
In Objective-C, you can achieve this by making use of Protocols. A protocol is basically the precursor to an interface in Java, so most of the behavior should come naturally.
A protocol declaration looks like the following:
#protocol Foo
-(void) foo;
-(int) boo: (int) arg;
#end
It may be implemented by a class. In the following case, you would say MyClass conforms to the Foo protocol.
#interface MyClass <Foo>
{
}
#end
#implementation MyClass
-(void) foo {
//do something
}
-(int) boo: (int) arg {
//do something else
return arg;
}
#end
Finally, you can pass them around like this:
-(void) someMethod: (id<Foo>) arg;
If you need to be more specific about the object, they can also be used like this:
-(void) someMethod: (NSObject<Foo> *) arg;
Related
I create one protocol method and I want to implement the protocol method in multiple classes
#protocol XMLProtocol <NSObject>
- (BOOL) hasAllRequiredAttributes :(NSDictionary*)attributeMap;
#end
I have use this following class methods
#import "XMLProtocol.h"
#interface MachineA : NSObject<XMLProtocol>
and its implementation method I will implement the protocol method
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
and also i use this protocol method in another class
#import "XMLProtocol.h"
#interface MachineB : NSObject<XMLProtocol>
and its implementation method I will implement the protocol method
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
my thought is where should I call the protocol method. I totally confused. How can i do this.
One way you can define a global implementation for your protocol method (if I understand correctly what you are asking) is defining a category on NSObject:
#implementation NSObject (XMLProtocol)
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
By doing like this every object will have that method. Don't know if this is sensible, but it's a way.
Another way would be defining a Machine base class from which both MachineA and MachineB derive; the protocol method would be defined in the base class:
#interface Machine : NSObject <XMLProtocol>
...
#implementation Machine
- (BOOL) hasAllRequiredAttributes:(NSDictionary *)attributeMap {
return false;
}
....
#end
#interface MachineA : Machine
...
and any derived class could redefine it, if required.
This is not as "global" as the NSObject category, but it might be a better solution if you can define a base class for all the classes that need implement that protocol.
You must write the implementation of the method in both classes, even if the implementations are identical.
In you particular situation notification would be great help full to you. Notification works same like protocol except it broadcast the message. so you could receive that call on multiple classes.
if you want to done with protocol than also it is very easy. just make sure you current view controller is referenced with delegate (i.e. obj.delegate = self). you can implement that on -viewWillAppear. so your current view controller only get called of that method. Delegate will only call one method at one place in a time.
IMHO a global protocol is not very good design for something as specific as XML parsing.
A #protocol doesn't have any implementation part by itself. It is just an API definition, think of it like a contract. Any class that conforms to a protocol must implement its mandatory methods and properties (there is a #optional clause).
For instance, you may have two implementations of an XML parser, one that works in iOS 4 and another one that works in iOS 5+. Both declared as conforming to XMLProtocol protocol. And both implementing - (BOOL) hasAllRequiredAttributes :(NSDictionary*)attributeMap;, let's imagine that they need to implement it differently.
Thanks to being compliant to XMLProtocol you don't care about the implementation details. You know that you'll pass an attribute map and you'll obtain a boolean indicating if it has all required attributes.
You call the method where ever you use those classes:
id <XMLProcotol> parser;
if (iOS4) {
parser = [[OldXMLParser alloc] initWithString:<#...#>];
} else {
parser = [[NewXMLParser alloc] initWithString:<#...#>];
}
/* you call the method without caring which parser class
* has been actually created thanks to the protocol
*/
if ([parser hasAllRequiredAttributes:theMap]) {
...
}
If the implementation of the methods are identical, you can make both a subclass of a common parent class that implements the common methods, present or not in the protocol.
I'm new to objective c and i want to create a class containing certain methods that can be called in any of my other classes, mostly helper methods. im still learning the syntax and i dont know how to declare it properly
kind of like in java Integer.parseInt( );
Thanks!
Static methods in objective-c are called 'class methods' and can be declared with '+' symbol (while instance methods with '-'), e.g.:
- (void) instanceMethod;
+ (void) classMethod;
To call class method use class name:
[MyClass classMethod];
Those are called (unsurprisingly) class methods. You can declare one by using + instead of - in the method signature, e.g.
#interface MyInteger : NSObject
+ (MyInteger *)parseInt:(NSString *)str;
#end
This method is then called on the class itself, e.g. [MyInteger parseInt:#"12"].
Of course, since this is C, if your class method doesn't actually have much relation to any particular class, you could just define it as a C function instead.
NSInteger myParseInt(NSString *str);
When you see a - sign in front of a method, it's an instance method. That means you can only call that method on an instance of a class.
If you want to create a class method, all you need to do is change that - to a +.
they are called class methods. they are declared and used like this:
#interface MONClass : NSObject
+ (NSString *)convertString:(NSString *)string;
#end
in use:
NSString * converted = [MONClass convertString:string];
I've got a simple question.
In Objective-C, when you have a method you want to call, with a return type of void, how you you call it from another method?
The way I've been doing it in my application is this:
[self nameOfMethod];
But that causes Xcode to spit out the following error:
Method '-nameOfMethod' not found (return type defaults to 'id')
Though it seems to still be executing.
Am I calling it right, or is there a better way?
Thanks!
I’m guessing you haven’t declared -nameOfMethod in the class interface and you’re calling it from another method whose implementation precedes the implementation of -nameOfMethod, i.e.:
- (void)someMethod {
[self nameOfMethod];
}
- (void)nameOfMethod {
// …
}
When the compiler is parsing -someMethod and -nameOfMethod hasn’t been declared in the class interface, it generates a warning because it doesn’t know about -nameOfMethod yet.
There are essentially two solutions for this. You could reorder the implementation file so that -nameOfMethod appears before -someMethod, but that’s not always possible. A better solution is to declare -nameOfMethod in the class interface. If -nameOfMethod is supposed to be called by clients of your class, place it in the corresponding header file. On the other hand, if -nameOfMethod is only supposed to be called inside your implementation file, use a class extension. Supposing your class is named SomeClass, this is what your header and implementation files would look like:
// SomeClass.h
#interface SomeClass : NSObject {
// … instance variables
}
// … external methods
- (void)someMethod;
#end
// SomeClass.m
#import "SomeClass.h"
#interface SomeClass () // this is a class extension
// … internal methods
- (void)nameOfMethod;
#end
#implementation SomeClass
- (void)someMethod {
[self nameOfMethod];
}
- (void)nameOfMethod {
// …
}
#end
Using class extensions, the order of method implementations won’t matter.
You need to make sure that your interface file contains a definition for nameOfMethod - so;
-(void) nameOfMethod;
You're calling it correctly, but make sure that the interface for your (void) method is in your .h file.
What is the difference in using object.variable and object->variable? When should I use object->variable?
As Objective C is a superset of C when using '->' syntax (which is similar to (*obj).var) you are accessing the instance variable (ivar) like in C-structure (well, classes in ObjC are just fancy C-structures).
Thus using the '.' implies that you're accessing the property. Properties is the feature that was added in Objective C 2.0 and allows you access your ivars via setter/getter methods, that could be created automatically (using #synthesize) or you can provide your own implementation. BTW it is absolutely not necessary for properties to have corresponding ivar. For example in #interface you declare:
#interface Ololo : NSObject {
//NOTE: there is no ivar named someText or _someText or whatever you want
}
#property(nonatomic) NSString* someText;
#end
Then in #implementation:
#implementation Ololo
#dynamic someText; //we're using this to tell compiler that we will provide getters/setters ourselves and it doesn't need to generate them (though it is not necessary to do that)
-(NSString*) someText {
return [NSString stringWithContentsOfFile: #"some_file_path"]; //we actually get value from file
}
-(void) setSomeText:(NSString*) str {
[#"asdas" writeToFile: #"some_file_path" atomically: YES];
}
#end
Actually you can do whatever you want in those methods. So using '.' is just shortcut for [obj setSomeText: #"hello"].
If you use . you are accessing a property of the class which you defined using #property and created with #synthesize. If you use -> you just access an instance variable, but its not really something you should use a lot. And the use is very limited. So don't make it difficult for yourself and use properties with .
The indirection operator (->) is inherited from C and can be used as a shorthand for accessing fields in a structure, to which you have a pointer.
As an example...
typedef struct IPhone {
int serialId;
} IPhone;
Here I have a traditional C struct which I can instantiate as follows...
IPhone *phone = (IPhone*)malloc(sizeof(IPhone));
Now to access its fields I can either do it the long way...
*(phone).serialId = 1123432324;
Or I can use the shorthand indirection operator...
phone->serialiId = 1123432324;
At the heart of every ObjectiveC class is a C struct. So what you're doing when you use the indirection operator is to jump back to old C syntax to backdoor into the underlying representation. It works, but it's not the prescribed ObjectiveC way.
object->variable is direct access to the variable. object.variable is a method call to the getter accessor method '-(id)variable'or setter accessor method '-(void)setVariable:(id)value' depending on context. You must write the accessor methods yourself or use #synthesize to generate them in order to use dot syntax.
Good programming practice dictates you always use accessor methods to access an instance variable from another instance. ie, dont use ->
This is an objective-c question.
I would like to call a method in an object, but there is no instantiation of the object. Is this possible?
The method I want to call is not a class method.
You can't call a method on an object that doesn't exist. But you can call a method on a class even if you have no instantiated objects of that class. (That's what alloc is in #fbrereton's answer -- a class method).
Class methods are declared and defined with a + instead of a -, are called on the class rather than the instance, and cannot access self or any instance variables in the class (for reasons that should be obvious).
Unless the method is static you will not be able to do this. static routines in Objective-C will be prepended with a +. For example NSObject provides these two routines (among many):
+ (id)alloc; // static - an NSObject instance is not required
- (NSString*)description; // nonstatic - an NSObject instance is required
One would make the respective calls like so:
NSObject* result = [NSObject alloc];
NSString* desc = [result description];
Sorry to nit-pick Chris' terminology, but we don't call a method on an object in Objective-C, we send a message to an object. When you send a message, the runtime will look up the appropriate method and call it. The distinction matters.
Perhaps you just want a plain-old C function. If you don't want a class method, and you don't want an instance method, that appears to be your only option. Don't be afraid of using C functions in Objective-C. Every technique has its place.
You can indeed invoke an instance method without an instance, provided it is functionally a class method (that is, it accesses no instance variables). Here's an example:
/*
Compile with:
gcc -framework Foundation inst_method_without_inst.m -o inst_method_without_inst
*/
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#interface Foo : NSObject {
}
- (BOOL)doSomethingWithThis:(NSString *)this;
#end
#implementation Foo
- (BOOL)doSomethingWithThis:(NSString *)this {
NSLog(#"Look, it's this: %#", this);
return YES;
}
#end
typedef BOOL (*my_sel_t)(id, SEL, NSString *);
int
main(void) {
Class cls = [Foo class];
SEL my_sel = #selector(doSomethingWithThis:);
Method m = class_getInstanceMethod(cls, my_sel);
// You could also use +[NSObject instanceMethodForSelector:] to get |m|,
// since |cls| is a kind of NSObject.
my_sel_t f = (my_sel_t)method_getImplementation(m);
BOOL result = f(nil, my_sel, #"Hello from an instanceless instance method invocation!");
NSLog(#"result: %d", (int)result);
return EXIT_SUCCESS;
}
You could get it to work even if the instance method accesses instance variables by allocating memory for it to work with (using either +alloc or class_getInstanceSize() plus malloc()) and passing a pointer to that memory as the first id argument to the implementation instead of nil.
While this is entertaining as an exercise, I can't think of a good reason to not just instantiate the class and use the standard messaging syntax and compiler support. In fact, the only reason we couldn't just do [(Foo *)nil doSomethingWithThis:#"BOO!"] here is that objc_msgSend() special-cases messages to nil with the result that NO is returned and nothing happens.