Is a CGContext an object? - objective-c

I've been programming since 2 months (so I'm quite a new) and i'm currently learning how to draw graphics for an iphone app but i need clarification on CGContext.
To create the current context we useCGContextRef currentContext=UIGraphicsGetCurrentContext(), here if I understand well(and please correct me if I'm wrong),UIGraphicsGetCurrentContext() create the current context but we assign it to a pointer of type CGContexRef.
Is the current context a object allocated memory on the heap or is it just a type of variable on the stack? I know we use pointer to work with the same data and avoid copying big memory blocks (right ?)
but what is really a CGContext, an object, a struct or whatever?

Short answer: CGContextRef is a pointer to a CGContext, which is a struct.
A CGContext is technically a struct, but it is conceptually an object, but in C, not Objective-C. The Core frameworks are object-oriented C frameworks.
Also, #dandan78's advice is good to help find out what things are.

It's an object disguised as an opaque C pointer. If you cast it to id it will behave like any other object (it wont need explicit retaining/releasing under ARC, can be added to collections, etc). The CGContext API requires it to be cast as a CGContextRef though.
The same goes for all of the Core Foundation SomethingRef types. Some, like CFArray can be safely cast to their equivalent Cocoa type (like NSArray). In general, it isn't that useful. It made it easier for people migrate their old Carbon-based code to Cocoa back when people still used Carbon.
Worth remembering that you can do po on a CFType in the debugger.

The point of these opaque types is that you don't need to know and don't need to care. Apple could change its internals with every release and we wouldn't know (and don't need to). Usually, FooRef types are pointers to something. Right now, it's defined as:
typedef struct CGContext *CGContextRef;
But what struct CGContext looks like, we don't know. It looks like it's really a CoreFoundation (and maybe Objective-C) object since there are the usual retain/release functions:
CGContextRef CGContextRetain (CGContextRef c);
void CGContextRelease (CGContextRef c);
The usual CoreFoundation memory naming patterns apply: you don't need to release a CGContextRef unless it was returned by a function that contains the words Create or Copy.

Related

Why doesn't objective-c allow pointers to a struct?

I was wondering why objective-c (ARC) does not allow me to use a pointer to a struct (NSPoint, in this case)
My code works without one, I just want to question why it doesn't allow it as I have not found a reason on Google for it.
My current guess is because structs cannot contain objects, but I want to double check that; and want to know where the struct itself is saved. Thanks!
When migrating to ARC, the compiler no longer allowed this due to the complexity of how the struct containing object pointers would be initialized, copied, moved, or destroyed.
Apple called this out in the Transitioning to ARC guides line the "ARC Enforces New Rules" section.
You cannot use object pointers in C structures.
Rather than using a struct, you can create an Objective-C class to manage the data
instead.
However this is now allowed in LLVM as of this commit.
To quote directly from the commit message:
Declaring __strong pointer fields in structs was not allowed in
Objective-C ARC until now because that would make the struct
non-trivial to default-initialize, copy/move, and destroy, which is
not something C was designed to do. This patch lifts that restriction.
Special functions for non-trivial C structs are synthesized that are
needed to default-initialize, copy/move, and destroy the structs and
manage the ownership of the objects the __strong pointer fields point
to. Non-trivial structs passed to functions are destructed in the
callee function.

Why did Apple previously typedef reference (pointer) types but not now?

I've been wondering why Apple uses data types in Core Foundation that are typedef'd to a pointer type while in Cocoa they are not.
As an example, you would reference a UIColor object like UIColor * while a reference to a CGColor object would be CGColorRef? Or NSURL * and CFURLRef? Why not just always use CGColor * and CFURL *? Or conversely, why no UIColorRef or NSURLRef types, since you never access a UIColor or NSURL directly anyway?
Or for example, why is it id and not id *, since it is actually a pointer and can in fact be typecast to void *?
Specifically, is there some reason Apple had a habit of doing this in their older frameworks, but stopped doing it in Cocoa? Is it simply a matter of style?
What Matt said, but there is a bit more to it.
The typedefs in the C based APIs also allow the implementation details to be hidden. For example, you can have the following without ever defining the __CFURL structure in a public header.
typedef __CFURL *CFURLRef;
Objective-C has long had these kinds of features in the form of categories and, recently added, the ability to move instance variable declarations out of the header file. Expect that, over time, you will see all instance variables removed from the public header files in the SDK.
Note that the Cocoa frameworks long, long, pre-dated CoreFoundation.
As for why id is used instead of id *, that dates back to when Objective-C was first created in the early 1980s. Specifically, the notion of the language was that you would build "software integrated circuits" that could be "plugged together" like real ICs. The goal was to keep the C bits around as implementation details and, ideally, not exposed in your APIs.
As for why you end up with NSString * instead of NSString, that is largely exactly because of the C underpinnings of the language. I wrote a fairly detailed answer to a slightly different SO question that is relevant.
You'll probably also find this answer relevant, too.
The reason for NSURL* vs CFURLRef is pretty much that it's just coding style. Cocoa is an Objective-C API and the general style in Objective-C is to not have a typedef whereas Core Foundation is a C API and the general style of it is to use a typedef. It's pretty much down to coding style.
id vs id* - I am not entirely sure with that, but my guess is it's historical and they just wanted to have the base "object" to be without the *. I don't know for sure the history of that, though. But again it'll just be a style thing.

Using a custom allocator in an iOS library

I'm creating a library that will be used by multiple types of iOS apps. Part of my API allows a user to specify routines that will be used for the library's allocations. My library is implemented mostly in C++, so this has been straightforward so far.
However, I've recently been adding some user interface functionality to the library: displaying a UIWebView using a custom view controller. I'm not sure how to ensure that my allocators are used for these objects.
How can I ensure that all of the Cocoa UI objects created by my library are allocated with my own functions?
I've tried a few things including overriding -initWithZone and calling CFAllocatorSetDefault before my -init. None of them have worked yet; and honestly I'm still a beginner with Objective C and Cocoa, so I'd like to know what the "correct" way to do this is.
I'm unable to find evidence of it now, but it certainly was the case that CFAllocator, malloc_zone_t and NSZone were all toll-free bridged. So you could just cast your allocator to an NSZone and pass it along.
I think the problem you're going to face is that NSZone was added at NextStep so as to allow a program to maintain multiple heaps, with the feeling being that it would allow programmers to keep related objects close to one another in memory — which is good for caching — and in some cases to throw away entire object graphs without walking the graph, which is obviously fast. However the former was of little benefit in practice and the latter is more likely to create problems than to be of actual benefit. So Apple has back-peddled from NSZones, gradually turning the related runtime calls into no-ops and removing detailed documentation. Apple's feeling is that, at the Objective-C level, you should not only maintain only a single heap (which is a side issue from your point of view) but that they'll always know best how to maintain it.
EDIT: an alternative idea is to replace NSObject's alloc, that being the thing that creates memory. The Objective-C runtime is well-defined enough that we know exactly what behaviour alloc exhibits, so that a vanilla version might be:
+ (id)alloc
{
Class *newInstance;
// we'll use calloc to ensure we get correct initial behaviour of
// everything equal to 0, and use the runtime's class_getInstanceSize
// so that we're allocating the correct amount of memory irrespective
// of whether this call has fallen through from a subclass
newInstance = (Class *)calloc(1, class_getInstanceSize(self));
// the thing that defines a class is that the first thing stored in
// it is the isa pointer, which points to the metaclass. So we'll
// set the isa pointer appropriately
*newInstance = self;
return (id)newInstance;
}
To replace NSObject's normal init, you'd probably want to define your alternative as a category method on NSObject named, say, customInit, then use class_getClassMethod, class_getMethodImplementation and method_setImplementation directly on [NSObject class] to switch it into place. See the Object-C Runtime Reference for documentation on those.

Objective C / Object Orientated Pointers

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.

Objective-c: Objects by value / Structs with methods / How can I get something like that?

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.