I have been playing with objective C a little and am finding it a great language..
Coming from C# i found pointers a little hard but now i understand the concept and how to use them..
ie:
MyObject* x = [[myObject alloc] callinitializer];
which create a new object on the heap and a pointer on the stack..
but can somebody please explain why to access the objects properties you do this:
[x setsomeprop: #"I Like Pizza"];
instead of this:
[*x setsomeprop: #"With Pineapple"];
without the dereferencing star arent we just working with the pointer instead of the object itself??
Confuesd!
Thanks
Daniel
No. The bracket syntax is a language feature specifically for objects - it dereferences the pointer automatically.
Partly this is just a result of how method dispatch works in a dynamic language like Objective-C. There's almost nothing useful you can do with a dereferenced object pointer in Objective-C.
Given that all objects are stored on the heap, and manage their own lifecycle with retain/release (or via garbage collection), a pointer to the object is exactly what you want to use in 99% of all situations.
As it turns out, essentially the same mechanism is used in C# and Java - object references are pointers, which is why assigning one reference to another makes them point at the same object, rather than copying the object.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
what is the point of pointers in objective language
I am confused as to when and why pointers are used in Obj-C code. I am new to Obj-C and have a good grounding in C++ from an intro course at my university.
NSDate *now = [NSDate date];
Why is a pointer used here (and what exactly is its purpose?), and not here...
NSUInteger arrayLength = [<some array> count];
I am much more comfortable with the second example, but the first is still puzzles me.
It's the wording of the typedefs of Apple which are confusing.
NSUInteger
is just a fancy typedef for unsigned int; therefore it's a scalar type and not an object; you don't need a pointer to it in general for such a simple use case.
However,
NSDate
is a Foundation class; it means that its instances are proper Objective-C objects. As you probably know, Objective-C is a fully dynamic language: no static instances of classes are permitted, so every object is essentially a pointer (well, rather the allocated memory behind the pointer). So when you work with Objective-C objects, you always need a pointer to them.
Well, there are a few fundamental differences between Objective-C and C++. In Objective-C, there is actually a "generic object" (type "id"), and you can pass objects around without worrying about classes.
One of the implementation details that makes this possible is that Objective-C doesn't have "static" objects; all objects are created through the equivalent of "new" and are accessed through a pointer (string literals might be different, but they are still of type "NSString*"). It's just the way it is in Objective-C; you simply cannot have an "NSString MyString".
Because of this, the whole "objects are just objects and the compiler doesn't actually what you're dealing with" is possible because all objects are just simple pointers -- they are all the same size. The compiler can pass them around without knowing what they are, you can store them in containers without the containers knowing what they are etc.
Objective-C and C++ may both be "object-oriented" extensions of C, but they are quite different nonetheless.
EDIT: you can write stuff like "NSString* MyString" so the compiler knows what kind of object it is dealing with, but that's just convenience: you can still put other objects into that pointer (and, in fact, since the "new" equivalent usually returns id, one of the more common mistakes that I make is to "new" a different class from what the pointer says)
On the positive side, the compiler will warn you if you assign e.g. an NSWindow* to MyString, and it will also warn you if you call "open" on MyString. However, this is just an added benefit from the compiler; you could just as well declare everything as "id", or cast away the warnings.
In my previous question, I figured out that all Objective-C objects are declared as pointers. But in C and C++, pointers can be accessed from any function, global or not, and they seem unprotected.
How are they "protected" in Objective-C ?
ObjC does not police your use of pointers.
There is type checking at compile time, so if you have a pointer to an NSNumber, and use the variable that holds it to assign to an NSString, the compiler will issue a warning. However, this is easily overridden by casting the pointer, as shown below,
NSNumber *myNumberPtr = [NSNumber initWithInt:99];
NSString *myStringPtr = (NSString *) myNumberPtr;
In this case, the compiler is told to keep quiet, but accessing myStringPtr as a string would cause 'undefined results', hopefully something obvious like a crash, but possibly something more pernicious.
Similarly, I could declare,
NSString *notActuallyAString = 0x897996789; // assigned some random value
Then when notActuallyAString is accessed at runtime, it is highy likely to cause a bad access exception as the pointer is almost certainly not pointing to an NSString, and quite possibly isn't a valid memory address at all.
This makes C (and its associated languages) powerful for low-level programming (if you actually know the memory mapped address of some hardware register, you can assign them in this way, and access hardware), but brings pretty clear risks.
It gets worse, because you may have a valid pointer at some point in the execution, but the memory that the pointer references is freed off at some later point. Then if you (wrongly) access that pointer, you again may well get an exception as the memory is no longer valid for the purpose the code assumes. Writing (assigning) a via a pointer that pointers somewhere it shouldn't is a common cause of memory corruption, which can be a devil to diagnose. For this reason, it's good practice (aka defensive coding) to make sure pointers that you've finished with are assigned to nil, so if you reuse those pointers when you shouldn't, you should get a symptom that is more easy to diagnose than some random memory corruption.
You need a good understanding of pointers to program in objC, and I would recommend reading the timeless classic reference book, 'The C Programming Language' by Kernighan & Ritchie which explains the basics of pointers, you can then build your understanding on how pointers and memory allocation is used in ObjC and C++.
A pointer, per se, does not have any kind of protection.
You should take a look to some basics of OOP; members can be of three types: public, protected or private. This is what decides if you can access the member from outside the implementation of the class itself (not considering, of course, some kind of hacking like accessing private members modifying directly the bytes of the object. You must not, however, do something like this because it's strongly against the OO philosophy: if a member is private there is a reason, and forcing the access to it will not give you any guarantee that your code will work with future versions of the library or in other machines).
In Objective-C members are protected by default. That's what give the protection you are looking for.
In Objective-C, instance variables are not exposed by default. In Objective-C 2.0, they are exposed by properties using the #property and #synthesize syntax. (Prior to 2.0, solely by explicitly written getter/setter methods.)
That notwithstanding, it is possible to access instance variables directly using the pointer operator syntax, e.g. NSString *bar = Foo->_text; even when text is not exposed as a property.
Further, you can now declare instance variables in your implementation file, to avoid having them exposed in public header files. If you are writing framework code, this offers some 'protection' against access to ivars outside of the property accessors since they are no longer visible.
as the title says, what is the difference between a pointer and an object.
Say I have this code..
NSString *red = [[NSString alloc]initWithFormat:#"%#"];
and this code..
NSString *blue = [NSString stringWithFormat:#"%#"];
Is it correct to assume that they're both pointers to an object and pretty much the same? And if so, how should I think of objects in my mind ?
I do apologize if the answer exists already, I did use the search function but I've only found examples of this in the C++ language and wanted to make sure how it was in objective-c.
In addition to Basile Starynkevitch and Bram's answer,
In objective C the difference between your code line is,
NSString *red = [[NSString alloc]initWithFormat:#"%#"];
**Above code says you own red object so it's your responsibility to release it.
NSString *blue = [NSString stringWithFormat:#"%#"];
**You don't own it someone else in your program deep down inside will own this and you don't have to release this.
I would suggest for more information reading Apple's documentation is GREAT! specially Learning, "Objective C programming guide"
Good luck!
PS : iOS 5 has new feature, memory management is done by iOS itself, Now developer can be more creative instead doing 3 grade mathematics of reference counting :)
Pointers are a C concept, and they're identical in C, C++, and Objective-C. They are simply an integer that holds the memory address where an object is stored. In your example, both of those messages dynamically create an NSString object. Where that object is stored in your application's memory is up to the OS to decide, and you really don't care. So the OS allocates some memory and stores an instance of NSString in it. It then gives you back a pointer to that object, which you can use to reference the actual object at a later time.
A pointer contains the address in memory where is stored the object.
Memory address Object
-------------- ---------
0
1
2
3
4
...
pointer ----> 10523 myObject1
10524
...
An object is an instance of a class. It takes up memory while and should be released when you are finished with it. The pointer is your reference to the object.
NSString *red = [[NSString alloc]initWithString:#"red"];
and this code..
NSString *blue = [NSString stringWithString:#"blue"];
red and blue are both pointers to different objects.
The importance difference here is that red is owned by you and blue is not
[[NSString alloc]initWithString:#"red"];z
returns an object that you own and have to release later
[NSString stringWithString:#"blue"];
returns an object that is not owned by you and will be released the next time the autorelease pool is emptied
These concepts are covered in The Objective-C Programming Language guide by apple (I pointed you to the specific section, its a huge document, but the section 'Objects, Classes, and Messaging' should be the most helpful to your questions)
i hope i can make this abit clearer.
the object is in memory. the pointer is like an arow to the memory where the object is.
see it like a directional sign to a building.. the building is the object, the directions are the pointers.
(I'm not an Objective C expert, but)
Think of objects as memory zones, a pointer refer to the zone but is not that zone.
Gross analogy: your car plate number is not your car. A number is a number (made of digits, or more abstractly an element of the set of naturals). A car is something you drive.
Also not an Objective-C expert. Here's my best guess.
Both of those types seem to be pointers. However, it looks like the difference is that the first (where you are using alloc) puts you in charge of the associated memory.
With the second type, if you instantiate the object, use it, whatever, and then it goes out of scope, the OS will likely clean it up for you. However, with the first type, you are in charge of releasing that allocated memory back to the OS.
I'm guessing that objective-C has some sort of reference counting and memory management built in to detect when that object is no longer being referenced anywhere, but the important part is that that object should persist beyond the scope of that declaration as long as you've still got a reference somewhere.
You can probably find a lot of information by reading this post: Objective-C pointers?
As far as the general definition of "object" and "pointer": Both of those types are pointers. One you are in charge the memory, and the other the OS takes responsibility for you. An object is simply defined as an instance of a class. A pointer is the memory address of that instance.
Sometimes I set objects to nil after releasing them to avoid crashes due to unexpected messages sent to dealloc'd objects.
Why doesn't the Objective-c runtime do this automatically when an object is finally dealloc'd?
Because pointers are passed by value and not reference. All dealloc gets is a local copy of the pointer; any changes it makes are discarded. Same goes for C's free and C++'s delete.
How would the runtime be able to track down all such references?
MyClass* a = [MyClass new];
MyClass* aCopy = a;
[a release];
a = nil; // Tidy up
[aCopy crashNowPlease];
Sometimes you can catch this sort of thing with Build & Analyze.
Also, you will be able to use zeroing weak references in the future (or, Mike Ash created such a facility).
In objective-C, the objects are always accessed as pointer.
Setting an object to nil simply change the pointer value, not the object value.
In your method, you have only access to the object's value, not to the pointer pointing to it!
As #David Dunham says, you can have more than one pointer to an object, so how would the compiler knows?
And more than that, to make things easier, imagine the following code :
int a;
int* aPtr = &a;
If you change a value, you can access the changed value via *aPtr right? But you can change a value as long as you want, it won't change aPtr value, as it is not the same variable!
Thus, even if you only have one pointer to your object, if you modify the object's value, you pointer will still point to the same address value!
What you are describing is called a zeroing weak reference. This feature is available in OS X 10.7's Automatic Reference Counting (ARC) runtime. Prior to 10.7, you can use Mike Ash's zeroing weak reference implementation.
Without explicit runtime support (and some small but unavoidable overhead), standard C-style pointers (id in Objective-C is a pointer to a structure) are just a memory address (an integer) and not tracked by the runtime. There's nothing stopping you from making copies of this value elsewhere in memory or from storing the value in an integer of the appropriate size and casting to an id later on (of course if you do any of this, you kill a baby seal). Thus, when an object is dealloc'd there's no way to know where (or how many) references there are to that object.
I'm starting to code in objective-c and I've just realized that objects can only be passed by reference.
What if I need an object to use static memory by default and to be copied instead of referenced?
For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.
I know I can use a c struct, but I also need the object Color to have methods that gets/sets lightness, hue, saturation, etc. I want my code to be object oriented.
Is there any solution to this?
EDIT: If for example I'm building a 3d game engine, where I'll have classes like Vector2, Vector3, Matrix, Ray, Color, etc: 1) I need them to be mutable. 2) The size of the objects is roughly the same size of a pointer, so why would I be copying pointers when I can copy the object? It would be simpler, more efficient, and I wouldnt need to manage memory, specially on methods that returns colors. And In the case of a game engine, efficiency is critical.
So, if there is no solution to this... Should I use c-structs and use c-function to work on them? Isn't there a better choice?
Thanks.
You can't do this. This isn't how Objective-C works (at least the Apple/GNU version*). It simply isn't designed for that sort of extreme low-level efficiency. Objects are allocated in dynamic memory and their lifetimes are controlled by methods you call on them, and that's just how it works. If you want more low-level efficiency, you can either use plain C structs or C++. But keep in mind that worrying about this is pointless in 99% of circumstances — the epitome of premature optimization. Objective-C programs are generally very competitive with C++ equivalents both in execution speed and memory use despite this minor inefficiency. I wouldn't go for a more difficult solution until profiling had proved it to be necessary.
Also, when you're new to Objective-C, it's easy to psych yourself out over memory management. In a normal Cocoa (Touch) program, you shouldn't need to bother about it too much. Return autoreleased objects from methods, use setters to assign objects you want to keep around.
*Note: There was an old implementation of Objective-C called the Portable Object Compiler that did have this ability, but it's unrelated to and incompatible with the Objective-C used on Macs and iOS devices. Also, the Apple Objective-C runtime includes special support for Blocks to be allocated on the stack, which is why you must copy them (copy reproduces the block in dynamic memory like a normal object) if you want to store them.
What if I need an object to use static memory by default and to be copied instead of referenced?
You don't.
Seriously. You never need an object to use static memory or be allocated on the stack. C++ allows you to do it, but no other object oriented language I know does.
For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.
Why do you not want the objects to be in static memory? What advantage do you think that gives you?
On the other hand it's easy to make Objective-C objects immutable. Just make the instance variables private and don't provide any methods that can change them once the object is initialised. This is exactly how the built in immutable classes work e.g. NSArray, NSString.
One solution that people use sometimes is to use a singleton object (assuming you only need one of the objects for your entire app's lifetime). In that case, you define a class method on the class and have it return an object that it creates once when it is first requested. So you can do something like:
#implementation MyObject
+ (MyObject *)sharedObjectInstance
{
static MyObject *theObject=nil;
if (theObject==nil)
{
theObject = [[MyObject alloc] init];
}
return theObject;
}
#end
Of course the object itself isn't what's being statically allocated, it's the pointer to the object that's statically allocated, but in any case the object will stick around until the application terminates.
There are times when you want to do this because you really only want one globally shared instance of a particular object. However, if that's not your objective, I'm not sure why you'd want to do what you're describing. You can always use the -copy method to create a copy of an object (assuming the object conforms to the NSCopying protocol) to manipulate without touching the original.
EDIT: Based on your comments above it seems you just want to have immutable objects that you can copy and modify the copies. So using -copy is probably the way to go.