Is the `id` type used often writing Objective C programs? - objective-c

I'm reading the book "Programming in Objective C" and he explained not too much on the id type and didn't give much exercise on it, so I'm wondering how often do you use id and if programmers most of the time avoid it? (since he explained some issues with it)
I'm sure it's used, would be great if you can mention some cases it is the only solution..like real life programming cases from some kind of app development.

id is the universal type in Objective C. It can represent a * of any Objective-C type, such as NSString *, NSArray *, etc. The neat thing about Objective-C is that you can send messages to id, and if the object on the other end understands the message, it will get processed as usual without the sender having to know the real type.
It's commonly used when defining anything generic. For example, NSArray is an array of ids; it's up to the programmer to put a specific kind of object in the container (e.g. NSNumber, NSString, etc.). It's used in a lot of other places in Objective-C (such as when defining IBActions for the interface builder, when defining init methods, etc.).

id is the generic object type in Objective-C. It can hold any object.
one real world example: parsing json you wont know, if the root element is a array or a dictionary. But id would take them both.
I use it a lot, but often in conjunction with a protocol definition: id<NetworkPrinterProtocol>. This means that it should be an object of any kind but it does fulfill the NetworkPrinterProtocol. Often used for defining delegates.
see WP: Objective-C — Dynamic Typing

The id is kind of like a catch-all data type. It is used to hold values of any type.
Common uses are for the return type of init... methods. It's used by the collection classes since they can hold any object. See the various getter methods return values and the various methods for adding/setting objects in the mutable version of collection classes.
It's also used in combination with protocols when you need a reference to an object that can be any class but must adhere to a protocol. Examples include many of the delegate properties such as the UITableView delegate.

Related

Bridge to objc, how can it knows arguments types?

I am writing a bridge from a language I am developing and ObjC.
There are several nice introspection C functions in the objective C runtime and I am able to retrieve arguments types for methods using method_getTypeEncoding.
The main problem is with object arguments which are returned as id (encoded as #) but what I would need is the real objc class name like NSString or NSNumber.
Is there a way to solve this issue without parsing the .h files?
Knowing something is an id allows you to know the size of the parameter, which is important when writing a scripting interface. Add another layer where you can dynamically verify assumptions using things like
[objectPassedIn isKindOfClass: [expectedType class]];
You want to be careful hardcoding things like, "Oh this is a string so look for __NSCFString" - because there's no way to know you'll get an instance of __NSCFString or another type. NSString is a class cluster - You could get any custom implementation back when using one.
The actual type of objects is not important to the Objective-C Runtime so you need to add your own layer. You might be able to get some useful info using Clang/llvm as a tool.

Searching Functions in Objective C

I have a strange task. I need to get an array that contains all the functions in an objective c object. I then need to be able to tell if each function is a class method or not. Then I need to get the names (preferably an NSString) of each parameter and the type each parameter takes. Is there a way to do this? If not, does anyone know how to access the keys and values coded in the NSCoding Protocol function -(void)encodeWithCoder:(NSCoder*)aCoder; without using NSKeyedArchiver? What I am trying to do here is display a list of properties required to initialize an object. All my objects use class methods to initialize themselves. I am making a level editor that allows me to edit properties that differ between objects and I don't feel like writing getPropertyList and initWithProperties functions for every single object since I have already done this by implementing the NSCoding protocol.
I need to get an array that contains all the functions in an objective c object. I then need to be able to tell if each function is a class method or not.
Easy enough: you want class_copyMethodList(), which gets you just the instance methods for that class. To get the class methods, pass the class object, e.g. class_copyMethodList(object_getClass([NSString class]), &count);
Then I need to get the names (preferably an NSString) of each parameter and the type each parameter takes.
The parameter name part is probably not possible. They're not included in the method's metadata, and I'm pretty sure that they don't survive compilation at all; digging them out of the executable if they're there would certainly not be easy.
The types, however, are easily accessible via one of two runtime functions: either method_getTypeEncoding(), which gets you the signature string for the method's return and arguments, or method_getArgumentType(), which will let you loop over the argument types (the returned strings use the same code as the full type string).
If not, does anyone know how to access the keys and values coded in the NSCoding Protocol function -(void)encodeWithCoder:(NSCoder*)aCoder without using NSKeyedArchiver?
Are you talking about the particular implementation that you've made for encodeWithCoder:? You want the list of ivars implied by [coder encodeObject:firstIvar forKey:#"firstIvar"]; [coder encodeObject:secondIvar forKey:#"secondIvar"];? I'm not sure what that has to do with method signatures, but if so, you could make an NSCoder subclass that creates a dictionary from when you pass it as the coder and send encodeWithCoder: to your objects (see this answer I posted the other day).
What I am trying to do here is display a list of properties required to initialize an object.
What about a class method that returns an array with the names of the properties?
+ (NSArray *)essentialPropertyNames {
return [NSArray arrayWithObjects:#"firstIvar", #"secondIvar", nil];
}
That would probably be less effort than picking through the runtime/class metadata and wouldn't be any less odd.
All my objects use class methods to initialize themselves.
That sounds unusual at best. In Cocoa, instances should use some form of -init to do their initialization.

Why do we have NSNumber and NSTemporaryNumber as two different classes?

I went through the source code of GNUStep's NSNumber's implementation to understand how does factory method implementation works there.
From there What I could understand was we have NSNumber with blank implementation for all initWithXYZ kind of methods. and NSTemporaryNumber was acting like an intermediate class in the hierarchy that implemented all the initWithXYZ methods where it actually created objects of specific types , autoreleased itself and returned the created object.
Also allocWithZone was overridden to avoid creation of NSNumber object and to create object of NSTemporaryNumber if it was so otherwise create objects of specific types.
What I didn't understand was, can't the same things be done by NSNumber itself ?
why give blank implementations at all , create the object of specific type and then autorelease self.
Also if we have implementations of createXYZ methods in NSNumber itself, why have initWithXYZ methods ?
If I have to implement a factory implementation for my project where say I have two mediaItems, video , audio and photo etc.
for which I have separate classes and corresponding enums which I pass to initWithMediaType who will create an object of correct child class, return it and destroy itself.
Have two classes like NSNumber and NSTemporaryNumber: say Media and TemporaryMedia, one with blank implementations other with implementations as mentioned above ?
Should I do something like this ?
Is this the way we have to implement Factory pattern in Objective C ?
My question might seem silly biut I come from a Java, C++ background where things looked different.
The purpose might be the same but I am finding it difficult to understand the way Objective C does it since it does not have abstract classes.
Link to the source:
http://www.koders.com/objectivec/fid46956186C20201706AFE1744AA7AFEEE09D1FE5A.aspx
The point is that NSNumber is a class cluster. The class you actually end up with may be an NSIntNumber, an NSFloatNumber or one of several others. They all respond to the same messages as NSNumber (and, usually in this pattern will be subclasses of it, but that isn't required) so it makes no real difference to the caller.
When you call alloc there's no way to know what sort of object to create, so a neutral type is created and returned instead. It substitutes appropriately upon receiving an appropriate init.
So this pattern is for the implementation of class clusters. You can ignore it if writing a class that provides only instances of itself.

How does an Objective-C method have access to the callee's ivars?

I was reading Apple's documentation, The Objective-C Programming Language (PDF link). On pg. 18, under The Receiver’s Instance Variables, I saw this.
A method has automatic access to the receiving object’s instance
variables. You don’t need to pass them to the method as parameters.
For example, the primaryColor method illustrated above takes no
parameters, yet it can find the primary color for otherRect and return
it. Every method assumes the receiver and its instance variables,
without having to declare them as parameters.
This convention simplifies Objective-C source code. It also supports
the way object-oriented programmers think about objects and messages.
Messages are sent to receivers much as letters are delivered to your
home. Message parameters bring information from the outside to the
receiver; they don’t need to bring the receiver to itself.
I am trying to better understand what they are describing; is this like Python's self parameter, or style?
Objective-C is a strict superset of C.
So Objective-C methods are "just" function pointers, and instances are "just" C structs.
A method has two hidden parameters. The first one is self(the current instance), the second _cmd (the method's selector).
But what the documentation is describing in page 18 is the access to the class instance variables from a method.
It just says a method of a class can access the instance variables of that class.
It's pretty basic from an object-oriented perspective, but not from a C perspective.
It also say that you can't access instance variables from another class instance, unless they are public.
While I would not say that it is a "slam" against Python, it is most certainly referring to the Python style of Object Orientation (which, in honesty, is derived from the "pseudo-object orientation" available in C (whether it is truly OO or not is a debate for another forum)).
It is good to remember that Python has a very different concept of scope from the rest of the world — each method more or less exists in its own little reality. This is contrasted with more "self-aware" languages which either have a "this" variable or an implicit instance construct of some form.

struct or class

I'm developing an iPhone 3.1.3 application.
I have a class, called Object2D, with fields and methods; which represent a shape. Object2D has a field that represents its size, and another field that represent its type.
Now, I need another class called Pattern, which is a set of shapes. In Pattern I'm going to have an array of shapes. From these shapes I only need their size, their type and their location inside pattern, I don't need any method.
I'm wondering it is better to have a new struct that represent a shape instead of using Object2D class.
I ask this because I think on memory performance. I'm not sure, but struct are smaller than classes and maybe it's better to use them instead of classes.
What do you think?
If you're looking at memory use, the difference is truly negligible in almost every situation. Objects are one pointer bigger than an equivalent struct.
The greater difference is in how you can use them. Objects can have methods and hierarchies and interact with the rest of Cocoa. With structs, you need to make custom functions for each struct type or hack together a pseudo-object system. On top of that, arbitrary structs don't interact well with the rest of Cocoa (Touch). For example:
If you store objects in them, you have to be very careful to do your own memory management correctly
You can't store them in NSArrays without creating an object wrapper (since NSArray is an array of objects)
You can't hook structs up in Interface Builder — it doesn't know anything about them
You can't do KVO or KVC with structs
In general, if you're working with a Cocoa-like framework, objects are a good default choice. Use structs once you've decided you really need them.
Objective-C classes are in fact structs, and, provided the instance variables are laid out in the same order as the structure members are, the only difference in size is the 4 or 8 bytes of NSObject's isa variable.
NOTE: the answer above assumes the legacy Objective-C runtime, without the use of #property and #synthesize directives, which could potentially affect their size.