When do you and when dont you need the * symbol (which is because in objective-c all variables like NSString are pointer variables)?
For example when do you need to do "NSString *" instead of just "NSString"?
In Objective-C, all object references are pointers, so you always need the pointer operator when you declare with an Objective-C object.
For other types, the use is exactly the same as in C. Use pointers when you want to pass data structures or primitive types by reference.
You use the asterisk for all Objective-C objects (such as NSDictionary, NSString, NSNumber).
For anything that is a primitive type (int, double, float) you don't need the asterisk. However, the NS prefix doesn't always mean that you must use an asterisk. Cocoa defines some structures (such as NSInteger, NSRect, NSPoint) that are are based on primitive types. You don't use the asterisk here either. An NSRect, for example, is just a structure of an NSPoint and NSSize, both of which are made up of 2 CGFloats (a primitive type).
You can pass a pointer to one of these primitive types or structures using the * notation.
Related
Is there a Swift equivalent to Objective-C's #encode?
For instance
#encode(void *) // -> #"^v"
Searching yielded nothing.
No, there isn't - because under the hood Swift classes don't use Objective-C introspection to do their work. There's no need to calculate this (like there is in Objective-C) in order to pass/call data.
However, if you need to use it dynamically at runtime (say, for interoperation with existing Objective-C methods) then you can either create an Objective-C call and pass the object through or (for simple types) write a lookup table.
The type encodings are listed at https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html which have the map, and it's possible to write a switch type statement that does the lookup.
But fundamentally if you have a type that you want to pass in and find it's objective c encoding type, you can use the NSObject's objCType method:
var i = 1 as NSNumber
String.fromCString(i.objCType)! == "q"
If you need to pass it through as an unmolested C string anyway, you may not even need to convert it back to a Swift string type.
Coming from Java et al, I'm not clear on the difference between these two declarations:
#property (nonatomic, readwrite) NSInteger score;
#property (nonatomic, strong) NSMutableArray *cards;
Why is the pointer, *, not a requirement on both property declarations?
I've seen this a lot in local variables too:
- (void)viewDidLoad
{
[super viewDidLoad];
int foo = 1;
NSString *bar = #"foo";
}
What's the difference between static allocation of primitive type int and NS types?
Objective-C objects are always allocated on the heap, so you always access them through pointers. Variables of primitive (or struct) types can be, and typically are, allocated on the stack and accessed without pointers.
If you're familiar with Java, it's basically the same semantics. Primitive types are accessed and passed around by value, objects by reference. The difference is that ObjC has (by virtue of its C lineage) syntax explicitly marking that difference.
Type names that start with an uppercase prefix in Apple frameworks aren't all ObjC classes. NSInteger is a primitive type just like int, so you can and usually do use it without pointers.
pointer is always used for referring to something at the heap but not when you referring to something on the stack.But
for some primitive types and simple structure which are accessed via the stack so you don't need to use pointer..
NSInteger is a primitive type, that means it will be stored locally on the stack. there is no need to use a pointer to access it, but if you want to use pointer then you can.
You can have a pointer to an NSInteger if you really want to with following way:
NSInteger *pointerToProcessID = &yourNsintegervar;
If you look at the definition of NSInteger you'll see that it is a typedef for a simple integer. Basically, all the non-object types are stored as simple values, while the types that are complex objects are typically pointer properties. There are a couple reasons why these more complex objects are stored as pointers:
Using the value, itself, instead of the pointer would require copying (that is, if you use a pointer, you can put the object somewhere else and you only need to copy the much shorter address rather than all of the content that happens to be in that object, and hence it is more efficient that way).
When using a non-pointer type, it is necessary to know the required storage space, which works if you know the exact type of the object, but fails in the case of inheritance (e.g. an NSMutableArray may add additional fields to NSArray, for example. If you were to use NSArray instead of NSArray*, then assigning from an NSMutableArray would be broken, because the system would only have set aside enough space for the fields in the base class and not for the derived class. When using a pointer, however, since the pointer size is the same for both the base and derived types, one can assign the pointer for a derived type to a pointer to the base type, and still have things work correctly).
Note that it is possible and safe to use a pointer type with these primitive types, as well; however, this is not done for efficiency reasons (it would create additional allocation and dereferencing where not necessary).
Could anybody explain me the difference between the pointer concept when using primitive datatypes like int and Objective-C data types like NSString?
thanks,
bala
Pointers are just that. They locate a memory location. You de-reference that pointer(location) to either primitive data type or user defined types as appropriate. I don't see a difference b/w pointers to user defined and primitive data types.
Assuming both pointer had been initialised properly dereferencing the former gives you an int, whereas doing so to the latter gives you a ClassA.
So in fact there is no difference, but the data instance those pointers are referring to.
Not sure why Objective-C decided to use NSNumber instead of float, double, etc. How is this type represented on disk?
NSNumber is toll-free bridged with CFNumber. In recent implementations of Core Foundation, CFNumber is a tagged pointer. This lets it be treated as an object, but without all the overhead of an object. Instead, the value is encoded in the object pointer (and isn't actually a pointer).
See Tagged pointers and fast-pathed CFNumber integers in Lion.
NSNumber is a descendant of NSObject, so it can go wherever an id can go: NSarray, NSDictionary, and so on. Primitives such as int and double cannot go in these classes, because they do not inherit from NSObject, and hence cannot participate in collections etc.
If I were to guess on the internals of NSNumber. I'd say it's a union and a type selector field. However, the beauty of encapsulation lets me successfully program to NSNumber without knowing a first thing about its representation (and not missing that knowledge).
One thing to keep in mind is that Objective-C is a super-set of C, so they didn't decide to use NSNumber instead of the primitive types (float, double, etc.) but in addition to them. If you don't need the functionality of NSNumber, then just use the primitive types and save the overhead of creating/destroying the objects. Many functions in iOS (notably the array type functions) only work with objects (descendants of NSObject). Therefore, if you want to pass some type of number to one of these functions, you need an object representation of it. This is where NSNumber comes in.
To quote the documentation on NSNumber:
NSNumber is a subclass of NSValue that offers a value as any C scalar
(numeric) type. It defines a set of methods specifically for setting
and accessing the value as a signed or unsigned char, short int, int,
long int, long long int, float, or double or as a BOOL. (Note that
number objects do not necessarily preserve the type they are created
with.) It also defines a compare: method to determine the ordering of
two NSNumber objects.
Note that internally the actual value is stored either as an integer or as a floating point number (within either a tagged pointer as Jay describes or a union in an object), depending on what value you are storing. This is important to know as if you try to store a number like "32.1" it will store it as a floating point number and when you retrieve it you will most likely get something like "32.09999999999999".
As far as storing it to disk, if you need to do this then you typically store it with encodeWithCoder and retrieve it with initWithEncoder which converts it to a format intended to be saved to disk and later read back in.
I'm trying to wrap my head around some of the differences in usage and syntax in C vs. Objective-C. In particular, I want to know how (and why) the usage differs for the dot operator and the arrow operator in C vs. Objective-C. Here is a simple example.
C Code:
// declare a pointer to a Fraction
struct Fraction *frac;
...
// reference an 'instance' variable
int n = (*frac).numerator; // these two expressions
int n = frac->numerator; // are equivalent
Objective-C Code:
// declare a pointer to a Fraction
Fraction *frac = [[Fraction alloc] init];
...
// reference an instance variable
int n = frac.numerator; // why isn't this (*frac).numerator or frac->numerator??
So, seeing how frac is the same in both programs (i.e. it is a pointer to a Fraction object or struct), why are they using different syntax when accessing properties? In particular, in C, the numerator property is accessed with frac->numerator, but with Objective-C, it is accessed using the dot operator, with frac.numerator. Since frac is a pointer in both programs, why are these expressions different? Can anyone help clarify this for me?
frac is actually not the same in both programs.
A C Fraction is a struct, which is a base type with no overloaded operators and is only really able to be constructed and destructed by default. If you define functions or fields on the struct, the way to access those properties in C is with the dot (.) operator. Objective-C maintains this operator when you use structs. For convenience, you can perform a dereference-and-dot operation using the arrow (->) operator (the two equivalent expressions you mention). Objective-C also preserves this when accessing structs.
An Objective-C Fraction in your example, however, is probably (one would assume) a pointer of at least type id, which is simply a classname and pointer to the instance of that class under the hood. It's also very likely to be a subclass of NSObject or NSProxy. These Objective-C classes are special in that they have a whole layer of predefined operations on top of just a C struct (if you really want to dig into it then you can take a look at the Objective-C Runtime Reference). Also important to note, an Objective-C class is always a pointer.
One of the most basic operations is objc_msgSend. When we operate on these types of objects, the Objective-C compiler interprets a dot (.) operator or the square bracket syntax ([object method]) as an objc_msgSend method call. For more detailed info about what actually happens here, see this series of posts by Bill Bumgarner, an Apple engineer who oversees the development of the Obj-C runtime.
The arrow (->) operator is not really supposed to be used on Objective-C objects. Like I said, Objective-C class instances are a C struct with an extra layer of communication added, but that layer of communication is essentially bypassed when you use the arrow. For example, if you open up Xcode and type in [UIApplication sharedApplication]-> and then bring up the method completion list, you see this:
Here you can see a bunch of normal fields which we generally access with square bracket syntax (like [[UIApplication sharedApplication] delegate]). These particular items, however, are the C fields that store the values of their respective Objective-C properties.
So, you can roughly think of it like this:
Dot operator on a C object
(at run time) Return value of the field
Arrow operator on a C object (pointer)
Dereference pointer
Return value of the field
Dot operator/square brackets on an Objective-C object (pointer)
(at compile time) Replace with call to objc_msgSend
(at run time) Look up Obj-C class definition, throw exception if something went wrong
Dereference pointer
Return value of the field
Arrow operator on an Objective-C object (pointer)
(at run time) Dereference pointer
Return value of the field
Now I'm definitely oversimplifying here, but to summarise: the arrow operators appear to do basically the same thing in both cases, but the dot operator has an extra/different meaning in Objective-C.
Dot-notation is a design choice. Since we always deal with pointers to objc instances, I'd guess the designers wanted something familiar, which also would not break existing programs. It was introduced in ObjC 2 - just a few years ago. Before that, you always had to use brackets for messaging.
Dot notation makes a difference though - it is not direct access, but a message.
That is:
obj.property = val;
// is the same as:
[obj setProperty:val];
// and not:
obj->property = val;
val = obj.property;
// is the same as:
val = [obj property];
// and not:
val = obj->property;
You can still write obj->ivar to access a pointer to object's members (if visible).
In your first example, Fraction is a struct.
In your second example, Fraction is an Objective-C class (and in iOS would likely be a subclass of NSObject).
C++ does not allow overloading of operator .. Therefore without additional information you can deduce that the dot notation you're seeing is an additional language construct integrated into Objective-C, rather than a C/C++ defined or overloaded operator.
As it happens, the dot notation is simply a design feature the implementors chose as shorthand for property access, entirely equivalent to the square bracket getter:
myObjCVar.prop == [myObjCVar prop];
The dot operator on objects is a special syntax for accessing objects' properties. It calls the property's getter or setter behind the scenes. So, for example, [#"hello" length] and #"hello".length are equivalent*. For all other types, the dot is the same as the C dot, and the arrow is always the same.
* Note: The accessor method won't always be named the same as the property. If it's a declared property and the declaration designates a special getter or setter method, that one will be used instead.
The dot and arrow notation are equally the same in C as it is in Objective-C (strict superset of ). I think the fundamental difference that needs to be distinguished is the difference between a struct and an Objective-C object.
The dot notation used for objects in Objective-C are used for properties that was introduced in Objective-C 2.0. However, with structs, the -> and dot notation between Objective-C and C are the same.