Why can't I use the classname instead of self in objective c - objective-c

It's just something which is not logical for me. Sure it's useful to call methods within in a class by the self-keyword. But why isn't it possible calling it by the own classname??
e.g.
[MyClassWhereIAmActuallyIn anyRandomMethod]; instead of [self anyRandomMethod];

Because that has a different meaning.
[self someMethod]
sends someMethod to the object, whose reference is stored in the (slightly magic) variable self.
[SomeClass someMethod]
sends someMethod to the class object (yes, classes are objects, too), which contains the meta-information for class SomeClass.
Two different objects ("receivers"). Also note, that there are class methods in Objective-C (i.e., you can take advantage of the fact, that classes are objects, and define new methods for them). Observe:
#interface SomeClass
- (void) someMethod;
+ (void) someMethod;
#end
These are completely different methods, intended for completely different receivers. The method tagged with - is an instance method (will be used, e.g., with self). The method tagged with + is a class method (and will be used with the class object).

You can call class method ('+') like that. Self is a pointer to an instance of your class in instance methods ('-'), self points to the singleton Class-object when you are in class methods ('+').

In OOP this is the difference between the class object and an instance of that class object. When you create a method, you specify whether it is a class method (+) or an instance method (-). Once the method is defined you need to call it in the appropriate way (on the class object or on an instance of that class).

Related

Create an instance from a Class that conforms to a Protocol

I'm trying to accomplish something like the following:
- (id<SomeProtocol>)instanceFromClass:(Class<SomeProtocol>)cls
{
return [[cls alloc] initUsingSomeConstructorDefinedInProtocolWithValue:_value];
}
However, I'm getting a No Known class method for selector 'alloc' error. How may I specify in my signature that I want to receive a class that conforms to a protocol? Or, if that part is correct, how may I create an instance from that argument using a constructor defined in the specified protocol?
Not sure why the compiler complains but you can fix by casting your parameter back to Class
- (id<SomeProtocol>)instanceFromClass:(Class<SomeProtocol>)cls
{
return [[(Class)cls alloc] initUsingSomeConstructorDefinedInProtocolWithValue:_value];
}
while still getting you the type checking you want for the parameter as hinted at in this SO answer: Declare an ObjC parameter that's a Class conforming to a protocol
Your use of the protocol is 'fine'. The issue is that the cls parameter is tagged as a class which conforms to a protocol that defines instance methods (the init method). This doesn't tell the compiler that the +alloc method is available because that is a class method on NSObject.
You can add the +alloc method to the protocol. Or you can do some casting to tell the compiler to trust you.
+ alloc is a method defined by the top level class NSObject. When you have a class like Class <SomeProtocol>, the compiler only knows that this is some class and it implements SomeProtocol but it cannot know if that is a subclass of NSObject or not, since in Obj-C you can define own top-level classes that don't inherit from NSObject (not that this is generally a good idea but it is possible).
There is a special "hack" in the compiler that in case the type is just Class, the compiler will always assume that it is a subclass of NSObject and would only fail at runtime in case it isn't. But this hack only works for the exact type Class and not for Class <SomeProtocol> which is a distinct type.
So what you can do is to either cast to Class, so the hack works again:
[[(Class)cls alloc] ...]
or you can also do that
[[cls.class alloc] ...]
in case that cls will be a subclass of NSObject at runtime because then it will have a + class method.
Note that if I call instanceFromClass: with a class, that does implement SomeProtocol but is no subclass of NSObject and also does not implement a + alloc method, both methods above will fail at runtime and the app will crash.

What is the functionality of method called class in objective-C

Hi I was studying about initialize class method in objective-C. I came across this code which confused me
+ (void)initialize {
if (self == [Car class]) // what is the use of method class??
{
// Makes sure this isn't executed more than once
_defaultModel = #"Nissan Versa"; // initializing the static variable _defaultModel
}
}
Here I know that we're using if (self == [Car class]) to check whether the self is referring to class itself or not. But what is the functionality of method class in [Car class] . I'm a newbie and I'm learning objective-C from couple of weeks when I searched for answers for this question all i got is difference b/w class methods and instance methods which I know. So please tell me what is the functionality of method class. Thanks in advance .
Two things to note here.
First, as you say the code is "using if (self == [Car class]) to check whether the self is referring to class itself or not". The method class returns the class object for Car, and self will be the same object if initialize is being called on Car.
Second, how could the class method initialize of Car be called on anything other than Car itself - it belongs to the class after all?
The answer to this lies in inheritance. The +initialize of Car will be called once before any instance of Car is created. However it will be also called once for every subclass of Car before the first instance of that subclass is created. E.g. if you have a class:
#interface Volvo : Car
...
#end
Then if Volvo has an +initialize then it will be called before the first instance of Volvo is created and Car's +initialize will also be called before the first instance of Volvo is created. This is why you will often see class initializers with an if statement to check for self being the class itself - it ensures the code is only executed once and not once per subclass as well.
HTH
[NSObject class]
Returns the class type of the object. See Apple's API
(By the way as a side note it's always good to google for the API before asking questions here)
There are two methods named class in Cocoa: the class method +[NSObject class], and the instance method -[NSObject class]. They do very different things, so do not get them mixed up. The former overrides the latter for class objects.
Here you are asking about the class method +[NSObject class], so that's what we will talk about. This method simply returns the object (class object) that it is called on, similar to -[NSObject self]. In fact, [Car class] can also be written as [Car self].
So why do we use a method that simply returns what it was called on? Why not just use the thing it's called on directly? This is due to a peculiarity in Objective-C syntax. In Objective-C, a class name like Car is not a valid expression (don't know why; the gods just made it that way). So we cannot just directly write self == Car, even though that's what we're really trying to say.
On the other hand, Objective-C has a special case for the message sending syntax [ ], where if the thing on the left side is a class name, the message is sent to the class object. So the "work-around" to get the class object for a class is to use the [ ] syntax to call a dummy "return self" method on it. In the Cocoa/GNUStep/OpenStep framework, there are two methods that can do this, +class, and -self. By convention, +class is used (which is really unfortunate, due to confusion with -class). After a while, you'll just get used to seeing [SomeClass class] and interpreting it as the SomeClass class object, whereas [some_obj class] gets the class of some_obj if it is not a class object.
(Note: In Smalltalk, which is where Objective-C inherited much of its stuff from, a class name is the expression for a class. So something like self == Car would be the correct way to write it. And the class method in Smalltalk always gets the class of the object, regardless of whether it's a class object or not.)

What does a variable defined as `Class<SomeProtocol> myClass` mean?

I am used to seeing things like id<NSCopying> myVar or MyObject<NSCopying> myVar, where we are stating that the variable in question can happily have NSCopying methods called on it without the compiler throwing a wobbly.
But I recently spotted some code that defined a variable like this:
Class<NSCopying> myClass;
I was wondering what this actually means as it seems subtly different from the top two examples. It seems like we're saying that the variable myClass can happily accept method calls from NSCopying - but having a class type able to accept these instance variable methods doesn't seem to make much sense.
It has occurred to me that variables of type class are technically objects themselves which is probably confusing me or the compiler (probably me!).
So I guess I'm asking:
What does something like Class<NSCopying> myClass; actually mean
How does Class<NSCopying> myClass; differ to something like id<NSCopying> myVar
Where could something like Class<NSCopying> myClass; be meaningfully used?
Notes:
I am just using NSCopying as an example and isn't integral to my use case
Wherever I refer to Class I mean the Obj-C keyword Class for declaring variables that are of type Class. I am not using this as a generic term for any class type.
Well I think it might mean that Class <NSCopying> myClass points to a class that implements NSCopying protocol. It can be useful if protocol has class method declarations and you want to call them.
For example:
#protocol NSSecureCoding <NSCoding>
#required
// The Secure Coding Guide should be consulted when writing methods that decode data.
+ (BOOL)supportsSecureCoding;
#end
id <NSCopying> myVar
Using id you can supply an instance of any type of class (so long as it implements the protocol, or you cast it to make the compiler trust you).
Class <NSCopying> myClass
Using Class means you can only supply a Class, not an instance.
Say you wanted your app to be configurable. Say you had a number of classes which offered a number of different features, but you didn't care about inheritance they had, just how to create and configure them. You could use a protocol that the class has to conform to and offer a method where the classes can be registered. Then you can instantiate those classes using the defined protocol without knowing anything else about the class.
Class<ProtocolName> is the type of a variable pointing to a class object with a meta class that conforms to ProtocolName. In other words: The class implements the methods from ProtocolName with class methods.
Example: NSCopying contains one required method:
#protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
#end
Class<NSCopying> means that there is a method
+ (id)copyWithZone:(NSZone *)zone;
in the class being pointed to. That is true for all NSObject derived classes and useful for using class objects as dictionary keys. See the documentation.

What's the difference of instance method and class method in Objective-C? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective-C: Class vs Instance Methods?
Objective-C - difference between class method and static method?
In ObjC, A single dash before a method name means it's a instance method. A plus before a method name means it's a class method. but what is the difference in programming?
The difference between a class method and an instance method is that an
instance method requires an instance of the class on which it will
(generally) operate. The message to invoke an instance method must be
sent to an instance of a class.
Probably the most common single use of class methods is object
factories; messages that you send to a class to create an instance
configured according to the parameters you've sent in. For example in
Cocoa the NSString class has several class methods named
stringWithSomethingOrOther: that will create a new NSString object and
hand it back to you.
On the other hand, NSString also has many instance methods -
operations which really have no meaning without an actual instance to
work with. A commonly-used one might be the length method, which tells
you how many characters are in the specific NSString instance to which
the message is sent.
Also see this.
What is the difference between class and instance methods?
An instance method is invoked on objects. A class method is invoked on class.
For example the line:
SomeClass *object = [[SomeClass alloc] init];
Here you can see that the "alloc" works on "SomeClass" and not on "object".
Whereas:
[object callMyFunction]; will act on "object" and not "class". This is an instance method.
The main difference with those two is the former one ie with single dash before it is only called by the instance of that class where it is declared ie one have to create one instance of that class means one object for that class and using . one can call the instance method
In class method, the later one can be called directly using the class name. To call class methods one dosen't need any object.
Please refer this link from apple developers documents

Class methods and instance methods - when/when not to use them?

I was wondering when and when not to use class methods and instance methods. I need some practical examples. I am really confused. Another question: can't we do exactly the same things with instance methods that we can with class methods?
Class methods: The method isn't tied to any specific object. In a way it acts like a free function in the class's namespace. No 'self' pointer. For instance [UIScreen mainScreen] is a class method because there's only one screen and there's no need to care about multiple 'screen instances'.
Instance method: Tied to a specific object.
This applies to most OO languages, not just obj-C.
At the implementation level, an instance method call contains a hidden pointer to a data structure (the object), a class method does not.
The practical question to ask is whether your call requires sending the call some specific data which is or could best be encapsulated as instance data inside an object, or not.
You (usually) can do the same thing with class methods as instance methods, but then you have to explicitly pass the object as a visible parameter in the call, which is uglier looking and also potentially disables some method override features of the Objective C language.
Use class methods for utility functions and Instance methods for object oriented stuff.
Eg. For Mathematical calculation (eg sin x ) use class method. But for invoking a behavior specific to an object.. use instance method ..
A class method as the name implies is bounded to the class. You can invoke them just with the name of the particular class. These can be normally exposed methods of a class.
For example
NSArray
+ (id)arrayWithArray:(NSArray *)array;.
You call it with the class name NSArray. What you expect is just a creation of a object of the type of that particular class. This doesn't need an object to invoke. Also these are very basic method required so its better to make it as a class method.
On the other hand instance method as the name implies is very much bound to the instance. Object is an entity that encapsulates state (ivars) and behaviors (methods) of a class. This can be very specific to the object.
For example
- (NSUInteger)count;
Lets take NSArray *a and NSArray *b. If a contains 5 items whereas b contains 4, instance methods called upon these instances will produce different results. And thats why we need instances to be initialized while invoking instance method. They work on the context(or state) of the object they are been called upon. Also they are not exposed as the class methods are.
Hope this helps.
If you want to use instance objet or instance variable you have to go with instance Methods.
Bcz Inside the class you cant access the Instance instance objet or instance variable.
Class methods are static methods.