Difference between class methods and instance methods? - objective-c

I always confusing to when i used of instance method and class method in programming. Please tell me difference between instance method and class methods and advantages of one another.

All the other answers seem to have been caught out by the incorrect tag that has now been fixed.
In Objective-C, an instance method is a method that is invoked when a message is sent to an instance of a class. So, for instance:
id foo = [[MyClass alloc] init];
[foo someMethod];
// ^^^^^^^^^^ This message invokes an instance method.
In Objective-C, classes are themselves objects and a class method is simply a method that is invoked when a message is sent to a class object. i.e.
[MyClass someMethod];
// ^^^^^^^^^^ This message invokes a class method.
Note that, in the above examples the selector is the same, but because in one case it is sent to an instance of MyClass and in the other case it is sent to MyClass, different methods are invoked. In the interface declaration, you might see:
#interface MyClass : NSObject
{
}
+(id) someMethod; // declaration of class method
-(id) someMethod; // declaration of instance method
#end
and in the implementation
#implementation MyClass
+(id) someMethod
{
// Here self is the class object
}
-(id) someMethod
{
// here self is an instance of the class
}
#end
Edit
Sorry, missed out the second part. There are no advantages or disadvantages as such. It would be like asking what is the difference between while and if and what are the advantages of one over the other. It's sort of meaningless because they are designed for different purposes.
The most common use of class methods is to obtain an instance when you need one. +alloc is a class method which gives you a new uninitialised instance. NSString has loads of class methods to give you new strings, e.g. +stringWithForma
Another common use is to obtain a singleton e.g.
+(MyClass*) myUniqueObject
{
static MyUniqueObject* theObject = nil;
if (theObject == nil)
{
theObject = [[MyClass alloc] init];
}
return theObject;
}
The above method would also work as an instance method, since theObject is static. However, the semantics are clearer if you make it a class method and you don't have to first create an instance.

If we don't want to create the object of class then we use the class method
if we want call the method through object of a class then we use the instance method

I don't know if we can talk of any advantage, this is rather a matter of what you are implementing.
Instance methods apply on instances of classes, so they need an object to be applied on and can access their caller's members:
Foo bar;
bar.instanceMethod();
On the other hand class methods apply on the whole class, they don't rely on any object:
Foo::classMethod();

Static member functions are informally called class methods (incorrectly). In C++ there are no methods, there are member functions.

Read up on the static keyword, that pretty much covers it.
MSDN:
http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx
Google search:
http://www.google.ch/search?aq=f&sourceid=chrome&ie=UTF-8&q=static+keyword+c%2B%2B

Class methods are used with classes but instance methods are used with objects of that class i.e instance
//Class method example
className *objectName = [[className alloc]init];
[objectName methodName];
//Instance method example
[className methodName];

instance methods use an instance of a class, whereas a class method can be used with just the class name. + sign is used before the Class Method where as single desh (-) is used before the instance variable.
#interface MyClass : NSObject
+ (void)aClassMethod;
- (void)anInstanceMethod;
#end
They could also be used like so,
[MyClass aClassMethod];
MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];
or another example is:
[
NSString string]; //class method
NSString *mystring = [NSString alloc]init];
[mystring changeText]; //instance Method

Like most of the other answers have said, instance methods use an instance of a class, whereas a class method can be used with just the class name. In Objective-C they are defined thusly:
#interface MyClass : NSObject
+ (void)aClassMethod;
- (void)anInstanceMethod;
#end
They could then be used like so:
// class methods must be called on the class itself
[MyClass aClassMethod];
// instance method require an instance of the class
MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];
Some real world examples of class methods are the convenience methods on many Foundation classes like NSString's +stringWithFormat: or NSArray's +arrayWithArray:. An instance method would be NSArray's -count method.

Related

self concept ,if i use self in class method not in instance method

#interface hello:SKScene
#end
#implementation hello
+(void)method{
[self here];
}
#end
main.m
[hello method];
here,when i call this class method without allocating memory for object then method self,belong to whom????
my question is self belong to class that contain the method calling on then because i did not define object then ,why i still can use self on this?????
is it still belong to class on which it calling ??please give me proper concept of self on instance method and class method.
When you refer to self in class method, self refers to the class, itself, not to a particular instance of that class. By using self rather than the actual class name in these class methods, it makes it easier to subclass the class in question. Specifically, the class method will be inherited, but the self references will now refer to the subclass rather than the base class. If you refered to the base class by name, this would not be true.
Consider this factory method:
#implementation BaseClassObject
// THIS IS WRONG
+ (BaseClassObject *)object {
return [[BaseClassObject alloc] init];
}
#end
And consider this subclass:
#interface SubClassObject : BaseClassObject
#end
Then consider code that does:
SubClassObject *object = [SubClassObject object]; // WRONG
The problem is that the object factory method will return a BaseClassObject rather than a SubClassObject. But that is remedied if we alter the definition of that factory class method to use self:
#implementation BaseClassObject
// THIS IS RIGHT
+ (instancetype)object {
return [[self alloc] init];
}
#end
Now when I refer to [SubClassObject object], I'll get an instance of SubClassObject rather than BaseClassObject.
Note: In my contrived example, it's rather important to use self. You may, though, encounter code where it does not appear to be immediately relevant (for example, you might have a base class, but no subclass at this time).
Even in this case, you probably should be in the habit of using self in these class methods, regardless, to "future-proof" your code, so that if you ever subclass this base class at some unforeseen date in the future, these class methods are more likely to function properly even when subclassed.
Just to add a little to Rob's answer: the class object is created automatically by the compiler and/or Objective-C runtime. (It doesn't matter to you which it is.) For all intents and purposes, it's permanent. There's no need for it to be managed.

Objective-C Class Method

My header class looks like:
#import "Card.h"
#interface PlayingCard : Card
#property (strong, nonatomic) NSString *suit;
#property (nonatomic) NSUInteger rank;
+ (NSArray *) validSuits;
+ (NSUInteger) maxRank;
#end
And my implementation:
#implementation PlayingCard
+ (NSArray *) validSuits
{
return #[#"♥︎", #"♣︎", #"♦︎", #"♠︎"];
}
+ (NSArray *) rankStrings
{
return #[#"?", #"1", #"2", #"3", #"4"];
}
- (void)setSuit:(NSString *)suit
{
if ([[PlayingCard validSuits] containsObject:suit])
{
_suit = suit;
}
}
- (NSString *)suit
{
return _suit ? _suit : #"?"; // if suit !nil return suit, else return ? string.
}
+ (NSUInteger)maxRank
{
return [[self rankStrings] count] - 1;
}
#end
So I understand that any method with a + means it's a Class method.
My question is, why must I use [PlayingCard classMethod] e.g. [PlayingCard validSuits] in the setSuit method whereas I can use [self classMethod] e.g. [self rankStrings] in the maxRank method?
I'm assuming it's something to do with the maxRank method being a class method whereas setSuit isn't. But could it be because setSuit is a setter?
I really don't know, I can't visualise what's going on here. I've only just started my foray into Objective-C and am coming from a Java background.
I have realised I can substitute PlayingCard in for self in the maxRank method without any error messages, however substituting self in for PlayingCard in the setSuit method gives me an error saying
No visible #interface for 'PlayingCard' declares the selector for 'validSuits'
Any explanation as to why this is the case and what's going on would be great. Thanks!
The meaning of self in methods
Every Objective-C method receives an implicit self argument. Instance methods receive the instance, while class methods receive the class object (remember: classes are objects).
If you want to send a class method, the compiler lets you use two types of syntax:
[ClassName classMethod]
[classObjectPtr classMethod]
The first syntax is used in [PlayingCard maxRank]. Here, the target is (explicitly) the PlayingCard class.
A class method already has a class object as a target for sending class methods: the self argument. So they can use [self classMethod] to send other class methods.
Why sending a message to self in class methods?
The advantage of the latter is that the class is not explicitly named. This makes it possible to override class methods in subclasses and call them from base classes.
You basically get the same dynamic method dispatch as with instance methods. This is actually a nice feature of Objective-C not present in Java or C++.
Instance methods would use the dynamic version by accessing their class and sending the message to that:
- (void)setSuit:(NSString *)suit
{
if ([[[self class] validSuits] containsObject:suit])
{
_suit = suit;
}
}
Now an imaginary subclass of PlayingCard could override the class method validSuits and implicitly alter the behavior of setSuit:.
self can be an instance or a class depending on the type of method declared.
- (void)setSuit: is an instance method, thus self is an instance inside this method declaration.
+ (NSUInteger)maxRank is a class method, thus self is a class inside inside this method declaration.
+ (void)classMethod;
- (void)instanceMethod;
- (void)setSuit
{ // self is an instance here
[self classMethod]; // warning, class method sent to instance
[self instanceMethod]; // works, instance method sent to instance
}
+ (NSUInteger)maxRank
{ // self is a class here
[self classMethod]; // works, class method sent to class
[self instanceMethod]; // warning, instance method sent to class
}
You tried to called a "class method" on self inside an instance method where self in an "instance".
In a class method, self refers to the class (it refers to an object that represents the class that obj-c runtime creates for you), so you can use it to call class level method.
In an instance method, self refers to the instance. If you want to call class level method in an instance method, you need to use the class name instead.
Java analogy of obj-c class methods is the static method. Java's this keyword is similar to self, except it can't be used to refer to a class.
setSuit is an instance method, and validSuits is a class method. However, both maxRank and rankStrings are class methods. Class methods are basically the same as static methods in C++

Find the Selector of a Class method

I'm quite a newbie in Objective C, though I have some background in Java reflection.
Here, I have a classic class method findAll that find all the domain objects from the database. The class Univers directly inherits from DomainObject
#interface DomainObject : NSObject
- (NSString *) execute : (NSString*) method withJson:(NSString*)json;
+ (NSString*)findAll: (NSString*)json;
#end
#implementation DomainObject
- (NSString *) execute: (NSString*) method withJson:(NSString*)json{
method = [NSString stringWithFormat:#"%#%#", method, #":"];
//method is 'findAll:'
NSString* result = [ self performSelector:
NSSelectorFromString(method) withObject:json];// Error here
return result;
}
#end
The code was working when findAll was NOT a class method (ie -findAll declaration), but now I have the error : NSInvalidArgumentException -[Univers findAll:]
It clearly seems that the runtime is looking for an instance method.
Any idea to find my class method ?
Instead of calling
NSString* result = [self performSelector:NSSelectorFromString(method) withObject:json];
you need to call
NSString* result = [[self class] performSelector:NSSelectorFromString(method) withObject:json];
for class methods.
After all it's the object instance's class that supposed to be calling the method, not the instance itself.
Short explanation: NSObject implements - (Class)class; (not to be mistaken with + (Class)class of similar effect, which NSObject implements, too!) which returns the Class object of your instance object. Keep in mind that in Objective-C in addition to plain instance objects, Classes are actual objects, too: objects of type Class, that is (vs. id, NSObject, …).
See the documentation for the -class method here.
Btw, you should probably wrap your method call into an conditional block to prevent exceptions caused by calls to missing methods.
SEL selector = NSSelectorFromString(method);
if ([[self class] respondsToSelector:selector]) {
NSString* result = [[self class] performSelector:selector withObject:json];
}
In general it's a common pattern in Objective-C to call an object's class method by receiving the class object via [object class].
Consider this case of a class called Foo implementing a convenience method for returning an autporeleased instance of itself (to be called via: Foo *newFoo = [Foo foo];):
While it would certainly be possible to implement said method like this (after all we know the object's class name, right?):
+ (id)foo {
return [[[Foo alloc] init] autorelease];
}
the correct way is this:
+ (id)foo {
return [[[self alloc] init] autorelease];
}
As the first one would cause problems with polymorphism in subclasses (Such as a subclass called FooBar, for which it should clearly be [FooBar alloc] …, not [Foo alloc] …. Luckily [[self class] alloc] solves this dynamically).
While this is clearly not the right place for a thorough explanation of this (rather offtopic one might say) it's certainly worth noting/warning about, imho.

What's the correct method to subclass a singleton class in Objective -C?

I have created a singleton class and I want to create a class which is subclass of this singleton class, what is the correct method to do it
I don't know about Objective-C in particular, but in general singleton classes should prevent subclassing. If you've got an instance of the base class and an instance of the subclass, then you've effectively got two objects you can regard as instances of the base "singleton" class, haven't you?
As soon as you've got two instances, it's not really a singleton any more... and that's leaving aside the possibilities that there are multiple subclasses, or that the subclass itself allows multiple instances to be created.
Of course you can change your base class so it just has a way of getting at a single "default" instance, but that's not quite the same as making it a singleton.
If Jon didn't convinced you to not do it, you should do it this way:
In your superclass, init your singleton instance with [[[self class] alloc] init] so then you always get an instance of the class with which you are calling the sharedInstance method. And you don't have to overwrite the sharedInstance method in your subclass.
[SuperClass sharedInstance] //-> instance of SuperClass
[SubClass sharedInstance] //-> instance of Class
I made an example "base class" for singleton, you can check it here: https://github.com/stel/DOSingleton
Jon Skeet makes a good point about whether you’d really have a singleton if you’re allowed to instantiate both the class and its subclass. Putting that aside, here’s a pattern you can use so that so you only have to define the shared-instance getter once, in the parent class:
// this code goes in the implementation of the superclass
static Sprocket *defaultSprocket;
+ (instancetype) defaultSprocket
{
if (defaultSprocket == nil)
defaultSprocket = [[[self class] alloc] init];
return defaultSprocket;
}
This approach has the following advantages:
Using [self class] allows e.g. [SprocketSubclass defaultSprocket] to return an instance of SprocketSubclass instead of Sprocket
Using instancetype allows the compiler to type-check the result of this method: it’ll be Sprocket when you invoke it as +[Sprocket defaultSprocket] but SprocketSubclass when you invoke it as +[SprocketSubclass defaultSprocket].
Notably, you can define this accessor method in the base class and then you don’t have to do anything in the subclasses!
(Hat tips to NSHipster for explaining why instancetype is so cool and bbum for reminding me of it recently.)
If what you are looking for is a quick way to setup new singletons. This pseudo abstract singleton base class is what I use:
Reusable base class
H
#define CREATE_SHARED_INSTANCE \
+ (instancetype)sharedInstance { \
static dispatch_once_t once; \
static id instance = nil; \
dispatch_once(&once, ^{ \
instance = [[self alloc] init]; \
}); \
return instance; \
}
#interface SharedObject : NSObject
+ (instancetype)sharedInstance;
#end
M
#implementation SharedObject
+ (instancetype)sharedInstance {
[NSException raise:#"Call to unimplemented sharedInstance" format:#"%# does not implement sharedInstance.", NSStringFromClass([self class])];
return nil;
}
#end
Then each subclass
H
#import "SharedObject.h"
#interface SomeSubclass : SharedObject
#end
M
#implementation SomeSubclass
CREATE_SHARED_INSTANCE
#end
...and use like any singleton.
[[SomesSubclass SharedInstance] someMethod];
If you call the abstract base class, or forget to include CREATE_SHARED_INSTANCE in your subclass, you will get a friendly exception raised.
This way you can setup a new singletons easily at no performance hit.
The simplest way to achieve this is implement the standard singleton accessor in both the class and the subclass. This way each class behaves as a proper singleton, that is there is only ever one instance of both. If you attempt to reuse the accessor of the parent class in the subclass and then if you make use of both classes, you run the risk of the accessor returning the wrong instance because their behaviour would depend on the order of how they are accessed.
You should not use instancetype for the singleton accessor to help prevent this mistake. You'll notice Apple don't use it for their singletons e.g. UIApplication and CKContainer.
If you would like existing code that accesses the super-class's singleton method be given an instance of the subclass then likely you need to redesign, see MrJre's answer.
I had a similar problem and the way I solved it is to create a singleton wrapper class which has all the extra functionality. This singleton class contains the original singleton (has the singleton instance as a member variable). This way you can avoid dirty tricks.
I had a similar problem, I had multiple targets that needed to have a slightly different singleton implementations: each target would include the base class + a specific subclass. This was achieved by writing the base class like so:
+ (SingletonBaseClass*) sharedInstance {
static SingletonBaseClass * sharedInstance = nil;
if (!sharedInstance) {
sharedInstance = [[[self class] alloc] init];
[sharedInstance customInit];
}
return sharedInstance;
}
The key difference is [self class] instead of the actual class name. That way when the we call: [SingletonSubclass sharedInstance] the correct object is instantiated.
Please note that this is a specific case, in the general case I agree with previous answers.
I had the same problem. This is how to solve: You need to use a static dictionary to subclass a singleton. For exemple:
Class A : NSObject -> Singleton
Class B : A
Class C : A
#implementation A
// Dictionary that holds all instances of API subclasses
static NSMutableDictionary *_sharedInstances = nil;
+ (instancetype)sharedInstance
{
id sharedInstance = nil;
#synchronized(self)
{
NSString *instanceClass = NSStringFromClass(self);
if (_sharedInstances == nil)
_sharedInstances = [NSMutableDictionary dictionary];
// Looking for existing instance
sharedInstance = [_sharedInstances objectForKey:instanceClass];
// If there's no instance – create one and add it to the dictionary
if (sharedInstance == nil)
{
sharedInstance = [[super allocWithZone:nil] init];
[_sharedInstances setObject:sharedInstance forKey:instanceClass];
}
}
return sharedInstance;
}
Now you can use [B sharedInstance] and [C sharedInstance] without problems!

What do the plus and minus signs mean in Objective-C next to a method?

In Objective-C, I would like to know what the + and - signs next to a method definition mean.
- (void)loadPluginsAtPath:(NSString*)pluginPath errors:(NSArray **)errors;
+ is for a class method and - is for an instance method.
E.g.
// Not actually Apple's code.
#interface NSArray : NSObject {
}
+ (NSArray *)array;
- (id)objectAtIndex:(NSUInteger)index;
#end
// somewhere else:
id myArray = [NSArray array]; // see how the message is sent to NSArray?
id obj = [myArray objectAtIndex:4]; // here the message is sent to myArray
// Btw, in production code one uses "NSArray *myArray" instead of only "id".
There's another question dealing with the difference between class and instance methods.
(+) for class methods and (-) for instance method,
(+) Class methods:-
Are methods which are declared as static. The method can be called without creating an instance of the class. Class methods can only operate on class members and not on instance members as class methods are unaware of instance members. Instance methods of the class can also not be called from within a class method unless they are being called on an instance of that class.
(-) Instance methods:-
On the other hand require an instance of the class to exist before they can be called, so an instance of a class needs to be created by using the new keyword. Instance methods operate on specific instances of classes. Instance methods are not declared as static.
How to create?
#interface CustomClass : NSObject
+ (void)classMethod;
- (void)instanceMethod;
#end
How to use?
[CustomClass classMethod];
CustomClass *classObject = [[CustomClass alloc] init];
[classObject instanceMethod];
+ methods are class methods - that is, methods which do not have access to an instances properties. Used for methods like alloc or helper methods for the class that do not require access to instance variables
- methods are instance methods - relate to a single instance of an object. Usually used for most methods on a class.
See the Language Specification for more detail.
The definitive explanation of this from Apple is here, under the 'Methods and Messaging' section:
https://developer.apple.com/library/mac/referencelibrary/GettingStarted/RoadMapOSX/books/WriteObjective-CCode/WriteObjective-CCode/WriteObjective-CCode.html
In brief:
+ means 'class method'
(method can be called without an instance of the class being instantiated). So you call it like this:
[className classMethod];
- means 'instance method'
You need to instantiate an object first, then you can call the method on the object). You can manually instantiate an object like this:
SomeClass* myInstance = [[SomeClass alloc] init];
(this essentially allocates memory space for the object then initalises the object in that space - an oversimplification but a good way to think about it. You can alloc and init the object seperately but never do this - it can lead to nasty issues related to pointers and memory management)
Then call the instance method:
[myInstance instanceMethod]
An alternative way to get an instance of an object in Objective C is like this:
NSNumber *myNumber = [NSNumber numberWithInt:123];
which is calling the 'numberWithInt' class method of the NSNumber class, which is a 'factory' method (i.e. a method that provides you with a 'ready made instance' of an object).
Objective C also allows the creation of certain object instances directly using special syntax, like in the case of a string like this:
NSString *myStringInstance = #"abc";