Is a C# "constructor" the same as an Obj-C "initializer"? - objective-c

I am very, very new to Obj-C, and will have a ton of questions. (I have the book "iPhone Programming, The Big Nerd Ranch Guide", but it doesn't address the differences between C# and Obj-C. Does anyone know of a doc that does address the differences?).
Anyway, my question is above...

In Objective-C, object allocation and initialization are separate operations, but it's common and a good practice to see them called in the context of the same expression:
MyClass *myInstance = [[MyClass alloc] init];
// ...
[myInstance release];
In C#, allocation and initialization happen when you use new:
MyClass myInstance = new MyClass();
The runtime allocates the instance and then calls the constructor.
So yes, the C# constructor is equivalent to the Objective-C initializer, but the usage is different.
Apart from this ... init in Objective-C is just a normal instance method, without any special semantics. You can call it at any point. In C#, constructors are very special static-like methods treated differently by the runtime and with special rules. For example, the C# compiler enforces calls to the base class constructor.

They are similar only as much as you can compare two completely different methods for creating an object. Checkout this information on the Objective-C Runtime.
The following is a very simple (but hopefully not misleading) explanation:
Objective-C
id object = [MyObject alloc]; // allocates the memory and returns a pointer. Factory-like method from NSObject (unless your class overrides it)
MyObject *myObj = [object init]; // initializes the object by calling `-(id)init`. You'll want to override this, or a similar init method for all your classes.
Usually written like this:
MyObject *myObj = [[MyObject alloc] init];
From what I know, the C# constructor allocates the memory and calls the appropriate constructor function to initialize the object.
A difference is that in C# you can't call an inherited constructor (see the bottom of the link above) but in Obj-C this will compile, but will give you wrong results.
#interface ClassA : NSObject
- (id) initWithInteger:(int)num;
#end
#interface ClassB : ClassA
- (id) init;
#end
#implementation ClassB
- (id) init
{
self = [supere initWithInteger:10];
return self;
}
// main
ClassA *a = [[ClassA alloc] initWithInteger:10]; //valid
ClassB *a = [[ClassB alloc] initWithInteger:10]; // will call init from classA, bypassing and not calling init for classB.
Just be careful with weak/dynamic typed language of Objective-C

They're similar, but not identical. Technically, a constructor fully creates and initializes an instance, while an initializer takes an already constructed instance (usually gotten through alloc) and sets the instance up so that it's ready to be used.
As for the differences between Objective-C and C#: They're two different and mostly unrelated languages. When you're learning a new language, trying to think of it as "Like this language I already know, but with these differences" can actually make it harder to learn, because there are a lot of differences and they're often subtle, so going in with assumptions from another language will confuse you. If you search around Stack Overflow, you'll find a lot of PHP programmers who start to learn a new language and immediately wonder "How do I do variable variables in this language?" It's like looking for a list of the differences between English and Chinese — you're better off not trying to treat one like the other. Keep in mind what you already know, but try not to assume any of it is the same in Objective-C.

Related

What is the purpose of declaring a protocol for a variable?

I have been reading about Protocols on Objective-C but I cannot grasp this:
Consider this line
Person <CoordinateSupport> *person = [[Person alloc] init];
What is the purpose of declaring the variable to conform to the protocol CoordinateSupport? Is this something just for compile time, so Xcode can warn me if I assign something different to person or is there any purpose at run time?
I cannot see how a variable can conform to a protocol. OK, a class is easy to see, because you can have a protocol defining methods that you want some class to follow but an ivar?
I am not seeing it.
The standard pattern when declaring that a variable conforms to a protocol is to give it the "any object" type, id. Declaring that a variable both has a specific type and conforms to a protocol is typically redundant – I'll explain why later. For now, let's talk about variables of type id<P>, where P is some protocol, and why they're useful. This type should be read as "an instance of any class that conforms to P."
To concretize the discussion that follows, let's define a protocol:
#protocol Adder
- (NSInteger)add:(NSInteger)a to:(NSInteger)b;
#end
I cannot see how a variable can conform to a protocol.
This one is easy. A variable conforms to an Objective-C protocol when it represents an instance of a class that implements all of the required methods in the protocol.
#interface Abacus : NSObject <Adder>
#end
#implementation Abacus
- (NSInteger)add:(NSInteger)a to:(NSInteger)b { return a + b; }
- (NSInteger)beadCount { return 91; }
#end
Given this Abacus class, you could, of course, create a new Abacus:
Abacus *a = [[Abacus alloc] init];
NSLog(#"%ld", (long)[a add:5 to:6]); // 11
NSLog(#"%ld", (long)[a beadCount]); // 91
But you could also declare a to just be of type id<Adder. Remember, that means the type of a is "an instance of any class that conforms to Adder."
id<Adder> a = [[Abacus alloc] init];
NSLog(#"%ld", (long)[a add:5 to:6]); // 11
NSLog(#"%ld", (long)[a beadCount]); // Compile error: No known instance method for selector 'beadCount'
The compiler complains because all we said about the type of a is that it is a class that conforms to Adder, and nowhere in the Adder protocol do we say anything about a method named beadCount.
What is the purpose of declaring the variable to conform to [a protocol]?
The purpose is for information hiding. When you want a class that conforms to Adder, you don't need to care about what the actual class is – you just get an id<Adder>. Imagine that Abacus is a system class, and you've written the following code:
- (Abacus *)getAdder { return [[Abacus alloc] init]; }
- (void)doWork {
Abacus *a = [self getAdder];
// Do lots of adding...
}
Then, in iOS 42, Apple comes up with a new innovation – the Calculator class! Your friends tell you that Calculator adds two numbers together more than twice as fast as Abacus, and all the cool kids are using it! You decide to refactor your code, but you realize that not only do you have to change the return type of getAdder, but also the types of all the variables to which you assign the return value of getAdder! Lame. What if you had done this instead:
- (id<Adder>)getAdder { return [[Abacus alloc] init]; }
- (void)doWork {
id<Adder> *a = [self getAdder];
// Do lots of adding...
}
Now, when you want to migrate to Calculator, you just need to change the body of getAdder to return [[Calculator alloc] init] and you're done! One line. The rest of your code stays exactly the same. In that case, you have hidden the true type of the instance returned from getAdder from the rest of your code. Information hiding makes refactoring easier.
Lastly, I promised to explain why something like Abacus <Adder> *a = ... is usually redundant. What you're saying here is "a is an instance of Abacus that conforms to Adder." But you (and the compiler) already know that Abacus conforms to Adder – it's right there in the interface declaration! As rmaddy points out, there are some cases where you want to talk about an instance that is either a given class, or a subclass thereof, and also specify that it conforms to a protocol, but those situations are rare, and most often specifying both a class and protocol conformance is unneeded.
For more information, check out Apple's Working with Protcols guide.

Objective C - is init a bad place to implement a factory?

I implemented the old init-as-a-factory pattern, but in one particular case (but not others!) I get a warning from the analyser regarding memory leaks. And indeed, looking at the Cocoa Memory Management Policy rules, it is alloc, not init, which can return +1-retain-count objects.
So it appears that:
Releasing self and returning a new object from init is, strictly speaking, against the rules.
Many places on the internet promote this technique, and because of the tandem nature of alloc/init this does work.
The analyser sometimes complains about this, and sometimes doesn't.
So... have we been doing this wrong all along?
you can implemented init like this, which should release self to balance the retain count from alloc call.
- (id)initWithSomething:(id)something
{
[self release]; // don't need this line for ARC
self = nil;
return [[PrivateSubClass alloc] initWithSomething:something];
}
and it if very often to implement init as a factory method. e.g. NSArray, NSDictionary, NSString
As gaige said, it will be much more clearer if you post a piece of code rather than explanations.
Anyway, you can move your factory to the class method, so you will have no such problem at all. I mean something like this:
MyClass* instance = [MyClass instanceWithParameters:params];
#interface MyClass
+ (MyClass*) instanceWithParameters:(ParamType)params;
#end
Without knowing what is the code that is causing the analyzer's behavior it's hard to tell, but as a general rule, here's a couple of compiler-friendly ways to define init/factory methods.
Classic alloc/init
- (instancetype)initWithParameter:(id)parameter {
if(self = [super init]) {
_parameter = parameter;
}
return self;
}
Usage
MyCustomClass * myInstance = [[MyCustomClass alloc] initWithParameter:foo];
This will produce an instance with a +1 retain count. Under ARC this will be automatically managed properly since it follows the NARC rule (New, Alloc, Retain, Copy).
For the same reason, in pre-ARC environments it has to be explicitly released by the client.
Custom factory method
ARC
+ (instancetype)canIHazInstanceWithParameter:(id)parameter {
return [[self alloc] initWithParameter:parameter]; // assuming -initWithParameter: defined
}
Pre-ARC
+ (instancetype)canIHazInstanceWithParameter:(id)parameter {
return [[[self alloc] initWithParameter:parameter] autorelease]; // assuming -initWithParameter: defined
}
Usage
MyCustomClass * myInstance = [MyCustomClass canIHazInstanceWithParameter:foo];
Both in ARC and pre-ARC the method returns an autoreleased instance (this is clearly more explicit in the pre-ARC implementation), which doesn't have to be managed by the client.
Remarks
You may have noticed the instancetype keyword. That's a handy language extension introduced by Clang, that turns the compiler into a dear friend when implementing your own constructors/factory methods. I wrote an article on the subject, which may be relevant to you.
Whether factory methods are preferable to init methods is debatable. From a client perspective it does not make much difference under ARC, provided that you carefully follow the naming conventions, even though I personally tend to expose factory methods in the interface, while implementing custom init methods only internally (as I did in the examples above). It's more a matter of style than an actual practical concern.

How to instantiate a class in Objective-C that don't inherit from NSObject

Given this:
Person.h:
#interface Person
{
}
- (void) sayHello;
#end
Person.m:
#import "Person.h"
#implementation Person
- (void)sayHello
{
printf("%s", "Steve");
}
#end
How do you instantiate the Person? I tried this:
Person *p = [Person new];
That doesn't work, nor this:
Person *p = [Person alloc];
[UPDATE]
I forgot to tell, I already tried inheriting from NSObject, the new and alloc works. I'm just curious if we can instantiate a class that doesn't inherit from NSObject?
You absolutely can do so. Your class simply needs to implement +alloc itself, the way that NSObject does. At base, this just means using malloc() to grab a chunk of memory big enough to fit the structure defining an instance of your class.
Reference-counted memory management would also be nice (retain/release); this is actually part of the NSObject protocol. You can adopt the protocol and implement these methods too.
For reference, you can look at the Object class, which is a root ObjC class like NSObject, that Apple provides in its open source repository for the Objective-C runtime:
#implementation Object
// Snip...
+ alloc
{
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
}
// ...
- init
{
return self;
}
// And so on...
That being said, you should think of NSObject as a integral part of the ObjC runtime. There's little if any reason to implement your own root class outside of curiosity, investigation, or experimentation (which should, however, not be discouraged at all).
You must:
Inherit from NSObject,
Do a "poor man's" class with your own mallocs, etc, or
Use Objective-C++ and create a C++ class.
Of course, neither of the other two fit into Objective-C storage management, and their call protocols, etc, are different.
There is (very likely) no good reason to not want to inherit from NSObject, but there are many good reasons to do so.
I would be curious as to your reason for why you don't want to inherit from NSObject. I would guess it stems from a lack of knowledge rather than a real need.
But even without knowing that reason: Don't do it. It's so hard to do this well in a way that it still plays nice with other Objective-C classes as to be virtually impossible.
Anyway, you're instantiating your objects in a way that hides what's really done. While in Java, you usually create instances via the default constructor method new, in Objective-C you instantiate by calling alloc on the class and then init on the instance:
Person *aPerson = [[Person alloc] init];
(It is possible to just use Person new, but I wouldn't do it because it hides what's really done from you)
You implement your class such that you inherit from NSObject and then, if necessary, write your own init method.
If you want to log to the console, use NSLog:
NSLog(#"Hello %#", #"Steven");
(#"" is a special constructor for a NSString. Strings in Objective-C are not byte arrays, but objects.)
you can't..
Alloc and new ..copy init all these methods are defined in NSObject..
You cannot also create your own since apple does not provide NSObject implementation class..so you have to inherit from NSObject or its subclass so that you can initialize your class

What's the difference between "class method" and "static method"?

I've worked with a few different languages such as Java, C#, and Objective-C.
In most languages, methods that don't require an instance of an object are called static methods. However, when it comes to Objective-C, some people get defensive when you call them static methods, and they expect you to call them class methods.
Why are they called class methods instead of static methods? What is the difference between a static method and a class method?
So my question is why are they called class methods instead of a
static method? What is the difference between a static method and a
class method?
From Wikipedia: Static methods neither require an instance of the class nor can they implicitly access the data (or this, self, Me, etc.) of such an instance.
This describes exactly what Objective-C's class methods are not.
An Objective-C class method very much requires an instance that is the target of the method invocation. That is, it requires an instance of the metaclass that describes the class object being invoked.
Unlike static methods, Objective-C's class methods can be inherited (which, in combination with having the aforementioned self, is exactly why many classes can share a single, simple, implementation of +alloc on NSObject without needing their own custom implementations) and invoking a class method goes through the exact same objc_msgSend* based dispatch mechanism as any other method call site.
Objective-C's class methods can be overridden across the class hierarchy and they can be swizzled. None of which is supported in languages that typically offer static methods in lieu of class methods.
The bottom line is that static methods and class methods are very different. While that difference is mostly transparent for day to day coding purposes, there are still situations where knowing how class methods work can save you a ton of unnecessary lines of code.
For example, you can't do this with static methods:
#interface AbstractClass:NSObject
+ factory;
#end
#implementation AbstractClass
+ factory
{
return [[[self alloc] init] autorelease];
}
#end
#interface Concrete1:AbstractClass
#end
#implementation Concrete1
#end
#interface Concrete2:AbstractClass
#end
#implementation Concrete2
#end
void foo() {
Concrete1 *c = [Concrete1 factory];
Concrete2 *d = [Concrete2 factory];
... etc ...
}
Because it's dynamically bound, not static.
Because it's really a class object's instance method.
Objective-C class method is actually an object's class object's instance method.
It's hard to describe with text. See nice illustration here.
http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html
Though class methods and static methods are in practice the same most of the time, they are different. With static methods the class is acting as a namespace qualifier. With class methods the class itself is an object and so class methods are to the class object exactly the same thing instance methods are to an instance; as a consequence you can do the following
#interface TestClass : NSObject
+ (void)classOrInstanceMethod;
- (void)classOrInstanceMethod;
#end
...
NSArray * arr = [NSArray arrayWithObjects:
[[[TestClass alloc] init] autorelease],
[TestClass class],
nil];
for( id obj in arr )
[obj classOrInstanceMethod];
which version of classOrInstanceMethod is called depends on whether obj is a class object or and instance. If you are familiar with the factory class pattern, this pattern is part of the Objective-C language.
This is purely a historical difference, mostly stemming from the fact that Objective-C was developed contemporaneously with C++, and before C++ or later languages like Java and C# had much influence. Objective-C was essentially a port of the Smalltalk object model to C, so its syntax and terminology don't necessarily seem as "C-like" as that used by C++. However, Objective-C was in no way bucking a trend by not using the term "static method", because that trend wasn't well-established back in 1983.

Objective-C Clarification; -/+ and *var

I'm teaching myself Objective-C from a book (Cocoa programming for mac OS X) and am about halfway through however I have two questions that aren't answered or defined in the book.
When defining class methods what is the difference between (assuming there in a .h file):
- (int) population;
+ (int) population;
The way I see it at the moment is that - methods require the class to be allocated and initialized first however + can be called statically without requiring allocation and initialization. E.g. (in a function in another class)
// Using -
Earth *world = [[Earth alloc] init];
int population = [world population];
// Using +
int population = [Earth population];
If that is correct, when should I use static methods and are they're any disadvantages with doing so.
When defining a var in either a function paramater or as an actual var in a function, does the use of * mean the var will be an object? e.g. (again in a header file.)
- (void) setPopulation: (NSNumber *) population; //Use of * as population is of NSNumber
- (void) setPopulation: (int) population; // population isn't a class so doesn't need *
Sorry if any of my terms don't make sense in the land of Objective-C such as static methods, etc. I'm a PHP and Ruby Programmer.
The -/+ in method declarations for Objective-C simply denote whether the method is a class method or an instance method. For example, with Objective-C, you cannot send an instance a message that was declared as a class method. For example:
#interface MyObject : NSObject
-(void)myInstanceMethod;
+(void)myClassMethod;
#end
// ...
MyObject* obj = [[MyObject alloc] init];
[obj myInstanceMethod]; // this is okay
[obj myClassMethod]; // this will fail
[[obj class] myClassMethod]; // this is okay
[MyObject myClassMethod]; // this is okay
[MyObject myInstanceMethod]; // this will fail
As to the second part of your question, Objective-C is a strict super-set of C. It adds classes but they are really C data structures whose implementations are hidden from you by the Objective-C runtime. Because of this, classes are always represented as pointers. In C, the * means that the variable is being declared as a pointer to some memory address. You can use pointers with primitive types in C as well, but Objective-C objects must always be referred to by pointers.
There are many great tutorials/introductions to pointers out there. I would suggest simply googling for C tutorial and pointers to learn more.
The + declaration is a class method, you need no instance to call it. Constructors/factory methods need to be class methods. The - declared an instance method, operation on a single instance. Each instance has its own independent state (member variables). This is a fundamental difference in OO programming! In general make most methods instance methods, except for utility classes.
You can see some discussion of when to use static methods in When should I write Static Methods?