id and Delegate Usage in Obj-C - objective-c

I am wondering what the following line of code is doing:
#property (assign, nonatomic) id <CoursePlannerDelegate> delegate;
Namely I am wondering about this portion of the line:
id <CoursePlannerDelegate> delegate;
It also shows up in other places:
#interface CategoryAddViewController : UIViewController {
UITextField *nameField, *weightField;
double maxWeight; //The maximum weight that can be allocated to this Category (max value of 100)
id <CategoryAddDelegate> delegate; //A Course Planner TVC
}

JustSid's answer is spot-on, but just a bit more clarification:
Compared to other OO languages, Objective-C lacks interfaces. Instead, Objective-C uses protocols, marked by the #protocol directive.
The id data type is an anonymous object. It's an Objective-C object -- that much is certain to the compiler. The compiler knows how much space to reserve for a pointer to the object, but it doesn't know at compile time if it's an NSString, a UIViewController, or what.
So, when you use the id type, you can specify (in angle brackets) a protocol that that anonymous object should adhere to.
In your code above, when compiling, the compiler will check any object you set to the delegate of CategoryAddViewController and double-check that you've implemented any required methods defined in the protocol.
Summed up, using the angle brackets when you use the id type will help the compiler tell you when you're doing something stupid.
All of this is for compile time -- if you need to be 100% paranoid at run time as well, you can use conformsToProtocol:#protocol(foo) to test for compliance (I believe this is a method on any NSObject).

It makes sure that you pass an Objective-C object that conforms to the given protocol. Thats it, if it doesn't, the compiler will throw a warning but nothing more.

Related

Why doesn't Xcode provide autocompletion for dot-notated properties on objects of type id<protocol>?

Given this protocol definition:
#protocol MyProtocol <NSObject>
#property (nonatomic, strong) NSString *someProperty;
#end
Why will Xcode gladly offer autocompletion for this statement:
id<MyProtocol> thing = [ThingManager currentThing];
[thing someProperty]; // Xcode offered autocompletion here
But it doesn't offer autocompletion when I try to access the same property using dot-notation:
id<MyProtocol> thing = [ThingManager currentThing];
thing.someProperty; // Xcode claimed there were
// "No completions" available
// after the period
Because id is a base type, Xcode and CLANG are uneasy about providing dot-syntax access against it because dot syntax is just syntactic sugar for a method call to an associated setter or getter in a normal object, but id has no defined method members. Looking at it from the C side of things, id is a typedef for a struct pointer that the compiler cannot see the members of, which means it cannot access them (never mind the fact that you would need to dereference id before dot-access would make any semantic sense).
Back to the Objective-C side of things, protocols don't actually add methods or properties to the classes that claim to implement them, rather they serve as a specifier to other classes that an object that conforms to a given protocol implements a series of methods. As for the method-syntax being completed, Xcode pools all of the given methods of all the files imported into a given .m file because, an object of type id can receive any message*
*of course, it can receive the message, but it'll still crash if it's unimplemented.
This is kind of a tangential answer, and a thought experiment.
But before that, I'll note that you could get your property autocomplete by skipping id, like this:
NSObject<MyProtocol> *thing;
thing.▮
But assuming you don't want the entire list of NSObject methods gumming up your completion, you could do something like
EmptyClass<MyProtocol> *thing = [ThingManager currentThing];
// completion list will be (close) to only the protocol props
thing.▮
EmptyClass serves a similar "OK, no promises!" role that id does, but autocomplete likes it. Here's EmptyClass:
NS_ROOT_CLASS
#interface EmptyClass
#end
#implementation EmptyClass
+ (void)initialize {} // required
#end
Mind you, the object in thing is not actually rooted on EmptyClass (can't be), so this is high fakery. However, it
vastly underpromises what thing can actually do.
doesn't (can't!) instantiate an EmptyClass object.
So why not? If you try really hard, you can cause problems like
EmptyClass *nooooo = [[NSClassFromString(#"EmptyClass") alloc] init];
which will immediately exception. But not really a tricky bug to avoid.
A gotcha wouldn't surprise me, but I don't know one right now. Please, leave a comment if you do.

Difference between class variables within braces and those declared with #property annotation

What is the difference between following code fragments?
No. 1
#interface HistoryJsonBean : NSObject
{
}
#property (nonatomic,retain) NSString * unit;
No. 2
#interface HistoryJsonBean : NSObject
{
NSString * unit;
}
#property (nonatomic,retain) NSString * unit;
I am a newbie, is there really a difference between above two codes?
The second has an instance variable called unit, the first does not.
Please, take time to read "The Objective-C Programming Language", available under the Documentation tab in the Xcode organizer.
The first syntax is relying on a feature of modern Objective C runtime systems to create the corresponding variable from a property definition. So, the second syntax is just Objective C 2.0 syntax used with older runtime systems.
Have also a look at this post from S.O.
EDIT:
The variable in the latter case is an ivar.
The property definition was originally just a short-way to define accessor methods for its ivar (with the proper memory management). Newer runtime systems relax the need to declare the ivar, and you can go by with just the property definition (which will also imply the allocation of memory to store the value associated to the property).
From the interface point of view, on a new runtime system there is no difference between the two syntaxes you mentioned. Now, if the runtime system handles them is two different ways, this could only be said by inspecting the implementation in the runtime systems source code. My guess is that there is no difference at that level either.

Where does the add(Propertyname) method come from?

I'm using the following lines to declare a property in my objective-c program.
#property (retain) int Money;
and the syntesize in my implementation file.
Now i wanted to make an addMoney method in my implementation to add an amount of money in my program. I was typing addMoney when i realized that Xcode was saying there is always a method with this name that i could override. It has the following signature.
-(void)addMoney:(NSSet *)objects;
and
-(void)addMoneyObject:(object-type *)object
where do they come from and who is calling them? AND how could i use it by myself? What must i attend to when using this?
This method does not actually exist. Xcode is helping you out by completing some common naming patterns. It's somewhat common to have a situation like this:
#class Thing;
#property (nonatomic, retain) NSMutableSet *things;
- (void)addThings:(NSSet *)someThings;
- (void)addThing:(Thing *)aThing;
Xcode is just trying to make it a little easier to type that. But the methods don't really exist unless you create them.
Side note: you can't retain an int, so I assume this isn't real code. That's fine. Do make sure your properties start with a leading lowercase (money). It's not just individual style. ObjC relies on Key-Value Coding for many things. That requires that things be named in a certain way or it won't work.
Is Money a ManagedObject (Core Data object)? If so, that method may be being created for you. Synthesized properties should provide setter and getter but that method would look like -(void)setMoney:(int)money and -(int)Money

What considerations determine whether to type and then cast to subtypes, or to use id?

If I have a class hierarchy in which subclasses require use of more specific types than those specified in the superclasses' ivars, is it better to declare the superclass ivar as id, or to type it and then cast where necessary in the subclasses?
For example I have a superclass which uses an ivar of type Thing:
#interface SuperClass {
Thing *_typedIvar; // OR
id anonIvar;
}
#property (nonatomic, retain, readwrite) Thing *_typedIvar;
#property (nonatomic, retain, readwrite) id anonIvar; // OR
Then in a subclass implementation I want to use a SubThing to get at its methodNotInThing
#interface SubClass : SuperClass {
}
#implementation {
- (void)aMethod {
SubThing *subtypedIvar = (SubThing *)self.typedIvar;
[subtypedIvar methodNotInThing];
// OR
[self.anonIvar methodNotInThing];
}
}
(I'm assuming here that the subclass has appropriately assigned a SubThing to the ivar).
I've used both approaches (in my thus far short time using ObjC), and am never quite resolved regarding which is best. I like the compiler checking offered by use of real types, along with being able to use dot syntax where appropriate. But the constant casting in subclasses gets pretty ugly, requires more code, and somehow tastes worse to me (which is hardly an argument, I suppose). However I like the fact in the typed version that the superclass in effect documents what subclasses should do with the ivar.
Which of the above would be the better approach, and why?
I would argue that using real types is better, despite the drawback of having your code littered with casts.
The programmer should be in control. Using id here is a bit careless.
Easier to follow, and therefore easier to debug.
While having casts everywhere may look messy, it forces you to be aware of what types you are expecting and again, this comes back to maintenance. It might work with id for right now, but if you have calls to id all over the place, how will you know why a particular one isn't working?

What is the different between an id and NSObject in Objective C?

What is the different between this:
id:
#import <objc/Object.h>
#interface Forwarder : Object
{
id something;
}
NSObject:
#import <objc/Object.h>
#interface Forwarder : Object
{
NSObject *something;
}
Thz u.
This Greg MILLER's blog post from the unixjunkie blog sums up the differences
Some extracts:
There's often confusion about the difference between the following three declarations in Objective-C:
id foo1;
NSObject *foo2;
id<NSObject> foo3;
The first one is the most common.
It simply declares a pointer to some Objective-C object (see /usr/include/objc/objc.h). id gives the compiler no information about the actual type of the object, so the compiler cannot do compile-time type checking for you.
Just because we know that an id is an Objective-C object does not mean that it points to an object that derives from NSObject, or that it even has common methods like retain and release.
One solution is to statically type our variable using NSObject* as shown in number 2 above.
This gives the compiler information about the class of the object pointed to by foo2 so the compiler can warn if you send a message to foo2 that an NSObject doesn't respond to. This means you can safely call retain, release, description, etc., but the compiler will warn if you call length or count or anything that an NSObject doesn't respond to.
Declaring an object as id<NSObject> tells the compiler that you don't care what type the object is, but you do care that it conforms to the specified NSObject protocol**.
** the protocol (#protocol) named NSObject. There is also a class named NSObject that does indeed conform to the NSObject protocol, but they are two different thing
The compiler will ensure that all objects you assign to that pointer conform to the required protocol.
A pointer typed like this can safely hold any NSObject (because NSObject conforms to the NSObject protocol), but it could also hold any NSProxy, because NSProxy also conforms to the NSObject protocol.
In english, the declaration id<NSObject> foo3; says "foo3 is a pointer to an object of any type that behaves like an NSObject".
This is very powerful, convenient, and expressive. In reality, we often don't care what type an object is, we just care that it responds to the messages that we want to send it (e.g., retain, release).
If you don't want (or can't have) any type checking, then use a plain id. This is very common for return types on methods that don't know the type of object they're returning (e.g., +alloc). It is also common to declare delegates to be type id, because delegates are generally checked at runtime with respondsToSelector:, and they usually aren't retained.
However, if you do want compile-time type checking, you must decide between the second and third cases. Well, let me just help you out—you want the third case! :-) I've very, very, VERY rarely seen a situation where NSObject * worked but id would not. And using the protocol form has the advantage that it will work with NSProxys.
The practical difference is that you do not need to typecast an id, but you usually need to typecast an NSObject * to something before using it. NSObject is the base class that almost all other classes are derived from where id is more of a language keyword.
An id responds to any method without a compiler warning; NSObjects only respond without warning to methods defined in NSObject, including the NSObject protocol.