Wednesday 20 March 2013

Multiple MOCs - Why?

I've been using Core Data with my current iOS app since early days. I've been learning more and more about the idiosyncrasies of Core Data and this magical thing called the 'Managed Object Context'.

What is the Managed Object Context?

I've heard it described as a scratchpad for you persistent data store. You can use it to represent the current state of your data store, or it can function to hold temporary data... that won't be or hasn't yet been persisted to your data store.

I think knowing these functions and thinking about them when you first start working with Core Data and managed object contexts is important. Otherwise, you ask yourself... 'Why, do I have to go through this thing to talk to my data store'.

After you understand this, you might ask yourself.. 'Well, why do I need to hold temporary data..? Or hold data before persisting it?'

I know of few cases where this is useful.
  1. Entity creation that spans multiple screens. As a ex-web developer I can think of what a pain it is to do this in the web world. If the user cancels half-way through, you need to ensure that nothing has persisted to the database. In web, you would have to have some fancy javascript or session storage going on to make this work. It's a huge pain! If you use something like an MOC to store this temporary object while the user builds it out, you don't have to persist it until it's completed.
  2. Data synchronization. Consider a situation where the user creates some entity that needs to be persisted to a back-end server. One strategy for doing this involves hold that entity in an MOC and only merging it to the main MOC and underlying data store when it has successfully been persisted to the back-end server.
I bet there are lots of other useful ways of using multiple MOCs. I'm just starting to explore this realm of Core Data and will update this post if I find other use cases!

Tuesday 12 March 2013

Property Attributes and Definition in iOS

Properties are an alternative to defining instance variables and their corresponding accessors methods. Let's go over the difference

Defining a Property vs. an Instance Variable


Without Properties

With Properties

What happens behind the scenes here are declarations for you accessor methods. This means with the above header and implementation code, you can operate on an instance of this object as follows.

Property Attributes


Each property has a set of attributes that describe the behavior of the accessor methods for that property. Here's an example.

There are three property attributes. Two of these must be specified and the 3rd has a default.
  1. The first attribute specifies either atomic or nonatomic. This has to do with multi-threading. Let's just say here that if you're doing a standard iOS app you should be using nonatomic.
  2. The second attribute specifies either readwrite or readonly. This tells Objective-C whether it should generate a getter and a setter(readwrite)... or just a getter(readonly).
  3. The final attribute has to do with memory management, which I've talked about in more detail here. The options here are weak, strong, or assign. Assign is the default which can be used for primitive values that don't point to an object. (like int)

iOS memory management with ARC

I've been learning iOS development over the last few months. I've been lucky enough to be working with iOS's ARC or automatic reference counting. This is what was introduced in iOS 5 and makes life a lot easier for iOS developers.

To understand how ARC works, a few concepts involving application memory need to be considered.

The Heap

This is the part of memory where all Objective-C objects are stored. When you send the alloc as a message to a given class, a chunk of memory is allocated from the heap for this new instance. This chunk includes space for the object's instance variables. However, if these instance variables are references to other objects, those objects are stored in their own heap allocation.

Pointers are used to remember where objects are stored in the heap.

The Stack

If the heap can be visualized as a heap of objects we reference via pointers, the stack can be visualized as a stack of frames (or chunks of memory). Frames from the stack are allocated as methods are executed and they store variables declared inside the method (i.e. local variables).

If you think about it. Most programs start by running some sort of main function. This would be the first frame on the stack. If it calls another method which then calls another method... each of these would get new frames allocated from the stack. As each method finishes, it's frame is popped off the stack and destroyed.

Pointers

These point to objects stored in the heap.

These can exist in 2 forms:

  1. As references from the local variables defined by methods using frames on the stack.
  2. As references from instance variables on another object stored within the heap
Memory Management

Heap memory is obviously not endless. It is important to destroy objects that are no longer needed to make room for new objects. It is also very important to not destroy objects that are STILL needed.

Object ownership is what helps in determining whether an object should be destroyed or not.
  • An object with no owners can be destroyed
  • An object with one or more owners can not be destroyed
iOS's ARC

Automatic reference counting was introduced in iOS 5 and takes care of deciding which objects have owners and which don't. And destroys those that don't! Before this, you would have to manage memory yourself using retain and release messages.

ARC now takes care of most of this for you, but it's still important to know what's going on behind the scenes in case you need to step in at some point.

How does ARC know an object doesn't have any more owners? It keeps track of all pointers to that object as they are created. Later, a number of things can happen to these pointers which mean they don't 'own' the object at the other end of the pointer.
  1. The pointer is changed to point to another object
  2. The pointer is set to nil
  3. The variable holding the pointer is destroyed
The last one is interesting because, as objects own other objects, which can own other objects.. the destruction of a single object can set off a chain reaction of loss of ownership and subsequent object destruction.

Your Hook in ARC

In Objective-C you're able to define variables as having strong or weak references. This ties directly into how ARC will manage the objects pointed to by these variables.

Strong Reference - This encompasses the discussion so far. If a variable is defined as pointing to an object, that object will never be destroyed.

Weak Reference - A variable that does not take ownership of the object it points to. If an object only has pointers from weak references pointing to it, it will be destroyed

Why have weak references? They're mostly used for retain cycles. This is when two or more objects have strong references to each other. This is bad because neither of these (or any objects they own) will ever be destroyed, even if all other pointers to both have been removed.

An interesting thing about weak references is that they know when the object they point to is destroyed. They are set to nil in this case. This will prevent any exceptions from occurring if the object containing that weak reference ever tries to use it.

Conclusion

So, if all those strong vs. weak variable definitions were confusing you (as they did me at first) there you go. It's the framework for memory management in Objective-C.

Monday 4 March 2013

AF Networking Simplifies iOS Http Requests

I wrote this post a month or so ago on implementing http requests using the built in iOS libraries. I've been building a iOS app with a Rails on Mongo instance functioning at the backend API. I just switched everything over to AF Networking, which has helped simplify my network calls greatly!

If you compare these two approaches you can see the simplicity AF Networking gets you!

And then you just implement the two methods given to the networking operation callback block. In this case, processResult and processFailure. It's so simple! And so much less code than the standard iOS option.

The AF Networking github page.