Let's say I have 2 classes, A and B. A is a singleton. I declare A in B, so I can access the singletons vars in methods in B.
B then creates an instance of another class, say class C.
C Then creates an instance of another class, say class D.
What I need to do is run a method in the instance of class B, from class D, and that's what is driving me nuts.
My first thought was to put a reference to the instance of class b, in my singleton (class A), something like...
sharedInstance.classBReference = self;
..and then declare the singleton in Class D, and then use something like this in class D instance...
[sharedInstance.classBInstance classBInstanceMethod];
But of course as soon as I did..
classB *classBReference;
In the header of my singleton, it game me the "unknown type" which I read about on here, so instead, I put a
#class classB;
above the #interface, and then I was able to declare...
classB *classBReference;
Without an error of unknown type, but in the init method of class B, this...
sharedInstance.classBReference = self;
Still gives me an error of type
"property classBReference not found on objet of type "class A*" (the singleton) did you mean to access ivar classBReference?"
And I have no idea why it's doing that, what's the solution? or is there a better way to do what I'm trying to do?
Dots and Arrows
The "dot notation" is a somewhat recent addition to Objective-C and provides a shorthand notation for accessors. If you have a pointer to an object (or a struct!), you cannot access its instance variables with . but only with ->.
Your line
sharedInstance.classBReference = self;
is exactly the same as
[sharedInstance setClassBReference:self];
The problem is that you don't have any such method -setClassBReference:. In order to set the instance variable, you must instead write
sharedInstance->classBReference = self;
#protected variables
After switching your line with this one, you may (if you haven't made it #public) see the error
Instance variable 'classBReference' is private
In this case, you need to alter your classA interface so that classBReference is declared to be #public. Your list of instance variables in classA should look something like
#interface classA : NSObject
{
//#protected
//(The #protected keyword is optional when at the beginning of the list; instance
//variables are protected by default, which is why you're needing to declare your
//instance variable classBReference to be #public (since classB is not a subclass
//of classA and consequently cannot access its protected instance variables).
//....
//some protected instance variables
//....
#private
//....
//some private instance variables
//....
#public
//....
//some public instance variables
classB *classBReference;
//....
#protected
//....
//some more protected instance variables
//Note that #protected is not optional in order to make the instance variables
//here be protected since they are declared subsequent to the prior #public.
//....
}
//....
#end
Using #properties
The case of classBReference
That being said, it is widely regarded as a better practice to use accessors rather than instance variables in general. In order to do this, you should add a property to your classA interface:
#interface classA : NSObject
{
classB *classBReference;
}
#property classB *classBReference;
#end
and synthesize the classBReference property to access the classBReference instance variable in classA's implementation as follows:
#implementation classB
#synthesize classBReference = classBReference;
The general set-up
The #synthesize is somewhat unclear on account of the fact that we have both an instance variable and a property with the same name. Some clarification is in order. In general, in a class's ("MyObject" in this example) #interface one declares an instance variable ("myVariable" in this example) and a property ("myProperty" in this example).
#interface MyObject : NSObject
{
SomeObject *myVariable;
}
#property SomeObject *myProperty;
#end
In the class's #implementation one has the line
#synthesize myProperty = myVariable.
The result of this code is that, given an instance
MyObject *object = //...
of the class, one is able to write
SomeObject *someObject = //...
[object setMyProperty:someObject];
and
SomeObject *someOtherObject = [object myProperty];
The result of calling -setMyProperty: on the instance of MyObject is that myVariable is set equal to the argument passed into the method--in this case someObject. Similarly, the result of calling -myProperty on the instance of MyObject is that myVariable is returned.
What does it get us?
Without the #property and #synthesize directives, one would have to declare the methods
- (void)setMyProperty:(SomeObject *)myProperty;
- (SomeObject *)myProperty;
manually and define them manually as well:
- (void)setMyProperty:(SomeObject *)myProperty
{
myVariable = myProperty;
}
- (SomeObject *)myProperty
{
return myVariable;
}
The #property and #synthesize provide some abridgment to this code. The amount of code that is generated for you becomes even more beneficial when you use various of the property attributes.
Note: There is more to say about the #property and #synthesize directives. For a start, not only can you write #synthesize myProperty; omitting the variable name, you can omit the synthesizing of myProperty entirely, and the variable names that are used automatically are different from one another in these two cases.
A Bit More on Dot Notation
The dot notation from your question provides another layer of abbreviation. Rather than having to write
[object setMyProperty:someObject];
you are now able to write
object.myProperty = someObject;
Similarly, rather than having to write
SomeObject *someOtherObject = [object myProperty];
you are now able to write
SomeObject *someOtherObject = object.myProperty;
It is important to note that this is just just notation. Though it "kinda looks like" we're doing simple assignment when we "set object.myProperty equal to someObject", that is not the case. In particular, when we execute the line
object.myProperty = someObject;
the method
- (void)setMyProperty:(SomeObject *)someObject
is executed. For this reason, dot notation is a subject of some contention. It is a convenience, but it is important to keep in mind what your code is doing.
The error message tells you the answer. You should define classBReference as property or use classBReference as ivar.
It sounds like you'd be less confused by avoiding the global variable (aka singleton). Give the C a reference to the B when the B creates the C. Give the D a reference to the B when the C creates the D.
If you need to avoid a retain cycle, make the back-references to the B either weak (if your deployment target is at least iOS 5.0) or unsafe_unretained (if your deployment target is earlier than iOS 5.0).
I have an interesting problem where I am trying to call class methods on an class which I essentially know nothing about in my test method. I can inspect its inheritance and any protocols it may implement but can't see an easy way to just call a method on it without getting tied up with an NSInvocation. The code below, albeit crudely, tries to demonstrate the problem I am having.
#interface ClassA : NSObject
+ (Class)classIsPartialClassOf;
#end
#implementation ClassA
+ (Class)classIsPartialClassOf {
return [NSString class];
}
#end
#interface ClassB : NSObject
#end
#implementation ClassB
- (id)init {
[ClassB testClass:[ClassA class]];
}
+ (void)testClass:(Class)classDecl {
/* obviously if you know the type you can just call the method */
[ClassA classIsPartialClassOf];
/* but in my instance I do not know the type, obviously there are no classmethods to perform selector such as the fictional one below */
[classDecl performSelector:#selector(classIsPartialClassOf)];
}
#end
Methods for getting implementations seem to return instance variants and I can't get them to fire on the static class itself.
Are my options limited to invocations or have I missed something obvious and should kick myself?
Thank you in advance for your help.
What is the problem? Your code
[classDecl performSelector:#selector(classIsPartialClassOf)];
should work. As will (simpler to write)
[classDecl classIsPartialClassOf];
Class objects are objects. And class methods are simply methods called on a class object.
"Methods for getting implementations seem to return instance variants and I can't get them to fire on the static class itself."
Then use objc_getMetaClass("ClassName") instead of objc_getClass. Class objects are objects themselves and are instances of their metaclass. If you pass the metaclass object to e. g. class_getMethod(), everything will be fine.
The top voted answer to this SA question ( Objective C Static Class Level variables ) outlines my question quite well but to it, I'd like to add one more criteria:
Issue Description
You want your ClassA to have a ClassB class variable.
You are using Objective-C as programming language.
Objective-C does not support class variables as C++ does.
I want to access ClassA's class variable from subclass ClassASub
or even better
4a. I want ClassA's method to access the class variable as it is, overridden in ClassASub
Any ideas? Or is this just bending Objective-C one step too far?
Just make a normal getter method for your class variable, and you can override it in the subclass. Just remember to access it through the method.
static SomeClass *gClassVar;
#implementation ClassA
+ (SomeClass *)classVar {
if (!gClassVar)
gClassVar = ...;
return gClassVar;
}
+ (...)someMethod {
[[self classVar] doSomething];
}
#end
Then,
static SomeClass *gClassVar;
#implementation ClassASubclass
+ (SomeClass *)classVar {
if (!gClassVar)
gClassVar = ...;
return gClassVar;
}
#end
So, when you call [ClassA someMethod], it will operate on the ClassA instance of classVar. When you call [ClassASubclass someMethod], it will operate on the ClassASubclass instance.
The idea of having variables of any sort attached to an object (class or instance) is a feature that is kind of "stapled on" to Objective C. Any time you want to do anything object-oriented using Objective C, start by working with methods. (Almost) everything else is just syntactic sugar for things you can do with methods.
The concept of private / protected / public is somewhat alien to Objective C, even though access control is supported for member variables. The best you can do for methods is to define them in a separate header (and this applies to class variables and properties, if we implement both using methods).
I have a class MyClass. I am exaggerating here, but let's say MyClass has 1000 instance variables. I then create a subclass called MySubClass with all the instance variables MyClass has, plus one more.
Question: given an object MyObj of class MyClass, is there an easy way to create a corresponding object MyDerivedObj of class MySubClass, such that the instance variables of MyDerivedObj are the same as the instance variables of MyObj? By "the same", I mean strongly the same, in the sense that if an instance variable of MyObj is a pointer to an object, the corresponding instance variable of MyDerivedObj should point to the same memory.
Inherently, every instance of an object will have a different id; a different address and a different allocation point in the heap.
Thus, the instance variables of A and the instance variables of B are always going to be at different locations.
Now, there is no reason why the instance variables of A and B can't be wrapped into a struct that is allocated separately. With that, then A and B could both have an instance variable that is a pointer to a single copy of a structure full of values.
In terms of setting all 1,000 ivars, it depends on what you want to set them too. If 0, then they will be set that way automatically on object instantiation. If you want to bcopy() in a templated set of values, I would suggest that you use a pointer to a structure and do a separate allocation. There is no way to bulk-set an object's instance variables without making assumptions about layout that will eventually bite you.
Do those ivars all have to be separate? If I had a similar problem, my first instinct would be to wrap them up in some sort of collection ivar (NS(Mutable)Array/Dictionary/Set) and then you can have a normal getter/setter on it and just do
myDerivedObj.collection = myObj.collection;
Assuming the collection was a property on MyObj class with "assign" memory management policy, I think this should preserve the memory reference.
(I'm still kind of new to this, so shoot down any flaws/errors in my logic.)
It the ivars are marked as #public or #protected, yes, they will be exactly the same.
I suggest you create a 'copy constructor' style initialiser for the parent class MyClass, and invoke that from the child class MyDerivedClass initialiser.
[MyDerivedClass initByCopying:someMyObject plusSomeNewProperties:stuff] ->
[MyClass initByCopying:someMyObject] ->
[NSObject init] -> // alloc, etc.
Here's some pseudocode:
#interface MyClass : NSObject {
int AA;
// ...
int ZZ;
}
#end
#implementation MyClass
-initByCopying:(MyClass*)other;
{
if (self = [super init])
{
self.AA=other.AA;
//...
self.ZZ=other.ZZ;
}
return self;
}
#end
#interface MyDerivedClass {
int AAA;
}
#end
#implementation MyDerivedClass
-initByCopying:(MyClass*)other withNewValue:(int)newVar;
{
if (self = [super initByCopying:(MyClass*)other])
{
self.AAA = newVar;
}
return self;
}
#end
I suspect that if you have 1000 member items you might want to consider using a property bag or kvc for all but the performance sensitive ones, which will make your initByCopying routine much simpler.
There may be a shortcut to implementing the copy constructor using the copy protocol, but I couldn't see how to make it easier than the example I gave above.
What's the difference between a class method and an instance method?
Are instance methods the accessors (getters and setters) while class methods are pretty much everything else?
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:
[MyClass aClassMethod];
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.
All the technical details have been nicely covered in the other answers. I just want to share a simple analogy that I think nicely illustrates the difference between a class and an instance:
A class is like the blueprint of a house: You only have one blueprint and (usually) you can't do that much with the blueprint alone.
An instance (or an object) is the actual house that you build based on the blueprint: You can build lots of houses from the same blueprint. You can then paint the walls a different color in each of the houses, just as you can independently change the properties of each instance of a class without affecting the other instances.
Like the other answers have said, instance methods operate on an object and has access to its instance variables, while a class method operates on a class as a whole and has no access to a particular instance's variables (unless you pass the instance in as a parameter).
A good example of an class method is a counter-type method, which returns the total number of instances of a class. Class methods start with a +, while instance ones start with an -.
For example:
static int numberOfPeople = 0;
#interface MNPerson : NSObject {
int age; //instance variable
}
+ (int)population; //class method. Returns how many people have been made.
- (id)init; //instance. Constructs object, increments numberOfPeople by one.
- (int)age; //instance. returns the person age
#end
#implementation MNPerson
- (id)init{
if (self = [super init]){
numberOfPeople++;
age = 0;
}
return self;
}
+ (int)population{
return numberOfPeople;
}
- (int)age{
return age;
}
#end
main.m:
MNPerson *micmoo = [[MNPerson alloc] init];
MNPerson *jon = [[MNPerson alloc] init];
NSLog(#"Age: %d",[micmoo age]);
NSLog(#"%Number Of people: %d",[MNPerson population]);
Output:
Age: 0
Number Of people: 2
Another example is if you have a method that you want the user to be able to call, sometimes its good to make that a class method. For example, if you have a class called MathFunctions, you can do this:
+ (int)square:(int)num{
return num * num;
}
So then the user would call:
[MathFunctions square:34];
without ever having to instantiate the class!
You can also use class functions for returning autoreleased objects, like NSArray's
+ (NSArray *)arrayWithObject:(id)object
That takes an object, puts it in an array, and returns an autoreleased version of the array that doesn't have to be memory managed, great for temperorary arrays and what not.
I hope you now understand when and/or why you should use class methods!!
An instance method applies to an instance of the class (i.e. an object) whereas a class method applies to the class itself.
In C# a class method is marked static. Methods and properties not marked static are instance methods.
class Foo {
public static void ClassMethod() { ... }
public void InstanceMethod() { ... }
}
The answer to your question is not specific to objective-c, however in different languages, Class methods may be called static methods.
The difference between class methods and instance methods are
Class methods
Operate on Class variables (they can not access instance variables)
Do not require an object to be instantiated to be applied
Sometimes can be a code smell (some people who are new to OOP use as a crutch to do Structured Programming in an OO enviroment)
Instance methods
Operate on instances variables and class variables
Must have an instanciated object to operate on
I think the best way to understand this is to look at alloc and init. It was this explanation that allowed me to understand the differences.
Class Method
A class method is applied to the class as a whole. If you check the alloc method, that's a class method denoted by the + before the method declaration. It's a class method because it is applied to the class to make a specific instance of that class.
Instance Method
You use an instance method to modify a specific instance of a class that is unique to that instance, rather than to the class as a whole. init for example (denoted with a - before the method declaration), is an instance method because you are normally modifying the properties of that class after it has been created with alloc.
Example
NSString *myString = [NSString alloc];
You are calling the class method alloc in order to generate an instance of that class. Notice how the receiver of the message is a class.
[myString initWithFormat:#"Hope this answer helps someone"];
You are modifying the instance of NSString called myString by setting some properties on that instance. Notice how the receiver of the message is an instance (object of class NSString).
Class methods are usually used to create instances of that class
For example, [NSString stringWithFormat:#"SomeParameter"]; returns an NSString instance with the parameter that is sent to it. Hence, because it is a Class method that returns an object of its type, it is also called a convenience method.
So if I understand it correctly.
A class method does not need you to allocate instance of that object to use / process it. A class method is self contained and can operate without any dependence of the state of any object of that class. A class method is expected to allocate memory for all its own work and deallocate when done, since no instance of that class will be able to free any memory allocated in previous calls to the class method.
A instance method is just the opposite. You cannot call it unless you allocate a instance of that class. Its like a normal class that has a constructor and can have a destructor (that cleans up all the allocated memory).
In most probability (unless you are writing a reusable library, you should not need a class variable.
Instances methods operate on instances of classes (ie, "objects"). Class methods are associated with classes (most languages use the keyword static for these guys).
Take for example a game where lots of cars are spawned.. each belongs to the class CCar.
When a car is instantiated, it makes a call to
[CCar registerCar:self]
So the CCar class, can make a list of every CCar instantiated.
Let's say the user finishes a level, and wants to remove all cars... you could either:
1- Go through a list of every CCar you created manually, and do whicheverCar.remove();
or
2- Add a removeAllCars method to CCar, which will do that for you when you call [CCar removeAllCars]. I.e. allCars[n].remove();
Or for example, you allow the user to specify a default font size for the whole app, which is loaded and saved at startup.
Without the class method, you might have to do something like
fontSize = thisMenu.getParent().fontHandler.getDefaultFontSize();
With the class method, you could get away with [FontHandler getDefaultFontSize].
As for your removeVowels function, you'll find that languages like C# actually have both with certain methods such as toLower or toUpper.
e.g. myString.removeVowels() and String.removeVowels(myString) (in ObjC that would be [String removeVowels:myString]).
In this case the instance likely calls the class method, so both are available.
i.e.
public function toLower():String{
return String.toLower();
}
public static function toLower( String inString):String{
//do stuff to string..
return newString;
}
basically, myString.toLower() calls [String toLower:ownValue]
There's no definitive answer, but if you feel like shoving a class method in would improve your code, give it a shot, and bear in mind that a class method will only let you use other class methods/variables.
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.
In Objective-C all methods start with either a "-" or "+" character.
Example:
#interface MyClass : NSObject
// instance method
- (void) instanceMethod;
+ (void) classMethod;
#end
The "+" and "-" characters specify whether a method is a class method or an instance method respectively.
The difference would be clear if we call these methods. Here the methods are declared in MyClass.
instance method require an instance of the class:
MyClass* myClass = [[MyClass alloc] init];
[myClass instanceMethod];
Inside MyClass other methods can call instance methods of MyClass using self:
-(void) someMethod
{
[self instanceMethod];
}
But, class methods must be called on the class itself:
[MyClass classMethod];
Or:
MyClass* myClass = [[MyClass alloc] init];
[myClass class] classMethod];
This won't work:
// Error
[myClass classMethod];
// Error
[self classMethod];
CLASS METHODS
A class method typically either creates a new instance of the class or retrieves some global properties of the class. Class methods do not operate on an instance or have any access to instance variable.
INSTANCE METHODS
An instance method operates on a particular instance of the class. For example, the accessors method that you implemented are all instance methods. You use them to set or get the instance variables of a particular object.
INVOKE
To invoke an instance method, you send the message to an instance of the class.
To invoke a class method, you send the message to the class directly.
Source: IOS - Objective-C - Class Methods And Instance Methods
Class methods can't change or know the value of any instance variable. That should be the criteria for knowing if an instance method can be a class method.
Also remember, the same idea applies to variables. You will come across terms like static, member, instance, class and so on when talking about variables the same as you would for methods/functions.
It seems the common term in the Obj-C community is ivar for instance variable, but I am not an Obj-C guy, yet.
An update to the above answers, I agree instance methods use an instance of a class, whereas a class method can be used with just the class name.
There is NO more any difference between instance method & class method after automatic reference counting came to existence in Objective-C.
For Example[NS StringWithformat:..] a class method & [[NSString alloc] initwihtformat:..] an instance method, both are same after ARC
Note: This is only in pseudo code format
Class method
Almost does all it needs to do is during compile time. It doesn't need any user input, nor the computation of it is based on an instance. Everything about it is based on the class/blueprint——which is unique ie you don't have multiple blueprints for one class. Can you have different variations during compile time? No, therefore the class is unique and so no matter how many times you call a class method the pointer pointing to it would be the same.
PlanetOfLiving: return #"Earth" // No matter how many times you run this method...nothing changes.
Instance Method
On the contrary instance method happens during runtime, since it is only then that you have created an instance of something which could vary upon every instantiation.
initWithName: #"John" lastName: #"Doe"Age:12 #"cool"
initWithName: #"Donald" lastName: #"Drumpf"Age:5 attitude:#"He started"
initWithName: #"President" lastName: #"Obama"Age:54 attitude: #"Awesome"
//As you can see the value can change for each instance.
If you are coming from other languages Static methods are same as class methods.
If you are coming from Swift, type methods are same as class methods.
Adding to above answers
Class method will work on class, we will use this for general purpose where like +stringWithFormat, size of class and most importantly for init etc
NSString *str = [NSString stringWithFormat:#"%.02f%%",someFloat];
Instance Method will work on an instance of a class not on a class like we are having two persons and we want to get know the balance of each separately here we need to use instance method. Because it won't return general response. e.g. like determine the count of NSSArray etc.
[johnson getAccountBalance];
[ankit getAccountBalance];