Monday, July 29, 2013

iOS- NSString to NSDate and NSDate to NSString

Here is the code snippet to show NSString convert to NSDate and NSDate convert to NSString


Input Date string and date formate
for example [aa dateFromString:@"your date" and @"dd/MM/yyyy hh:mm"];

+(NSDate*)dateFromString: (NSString*)dateString and: (NSString*)format
{
    
    NSDateFormatter *dateformatter = [[NSDateFormatter alloc]init];

    // Server sends Sydney time
    NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"Australia/Sydney"];
    [dateformatter setTimeZone:zone];

    // set locale, we use us date time style,
   // if you want to force to display 12 hour style or 24 hour style, you can set  en_US_POSIX force to     use 12 hour style
    NSLocale *locale = [[NSLocale alloc]initWithLocaleIdentifier:@"en_US"];
    
    // date string to NSdate
    [dateformatter setLocale:locale];
    [dateformatter setDateFormat:format];
    NSDate *date =[dateformatter dateFromString:dateString];

    return  date;
}

+(NSString*)stringFromDate: (NSDate*)date and: (NSString*)format
{

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:format];
     NSTimeZone *zone = [NSTimeZone localTimeZone];
    [dateFormat setTimeZone:zone];
    
    NSLocale *locale = [[NSLocale alloc]initWithLocaleIdentifier:@"en_US"];
    
    [dateFormat setLocale:locale];
    
     return [dateFormat stringFromDate:date];

}

Concurrency in iOS

First of all, let's understand some basic concept:
Main queue
This queue performs all its tasks on the main thread, which is where Cocoa and Cocoa Touch require programmers to call all UI-related methods. Use the dispatch_get_main_queue function to retrieve the handle on the main queue.

Concurrent queues
These are queues that you can retrieve from GCD in order to execute asynchronous or synchronous tasks. Use the dispatch_get_global_queue function to retrieve the handle to a concurrent queue.

Serial queues
These are queues that, no matter whether you submit synchronous or asynchronous tasks to them, will always execute their tasks in the first-in-first-out(FIFO) fashion. Use the dispatch_queue_create to create a serial queue. Once you are done with the queue, you must release it using dispath_release function.

Only one main queue, but you can create as many serial dispatch queues as you want. Tasks can be handed to dispatch queues in two forms: block objects or C functions.

Main subjects to handle concurrency, Grand Central Dispatch, Threads,Timers,Operation and Operation Queues.


Grand Central Dispatch
Performing UI-Related Tasks with GCD

use dispatch_get_main_queue, UI-related tasks have to be performed on the main thread.
Code Snippet,

       dispatch_queue_t mainQueue = dispatch_get_main_queue(); 

       dispatch_async(mainQueue, ^(void) {
       [[[UIAlertView alloc] initWithTitle:@"GCD" message:@"GCD is amazing!"
           delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show]; 
       });

Executing Non-UI Related Tasks Synchronously with GCD
use the dispatch_sync function



              void (^printFrom1To1000)(void) = ^{
              NSUInteger counter = 0; for (counter = 1;
              counter <= 1000; counter++){
              NSLog(@"Counter = %lu - Thread = %@", (unsigned long)counter,
              [NSThread currentThread]);
              } }; 


dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

           dispatch_sync(concurrentQueue, printFrom1To1000); 
           dispatch_sync(concurrentQueue, printFrom1To1000); 

The priority of the concurrent queue that GCD has to retrieve for the programmer.

DISPATCH_QUEUE_PRIORITY_LOW
Fewer timeslices will be applied to your task than normal tasks.

DISPATCH_QUEUE_PRIORITY_DEFAULT
The default system priority for the code execution will be applied to your task.

DISPATCH_QUEUE_PRIORITY_HIGH
More timeslices will be applied to your task than normal tasks.

Executing Non-UI Related Tasks Asychronously with GCD
Use dispatch_async


          dispatch_queue_t concurrentQueue =              dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        dispatch_async(concurrentQueue, ^{
              __block UIImage *image = nil;
             dispatch_sync(concurrentQueue, ^{ /* Download the image here */
             });
        dispatch_sync(dispatch_get_main_queue(), ^{

      /* Show the image to the user here on the main queue*/

        }); }); 


Performing Tasks After a Delay with GCD
use the dispatch_after and dispatch_after_f functions


             double delayInSeconds = 2.0;
             dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);

             dispatch_queue_t concurrentQueue =          dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 


             dispatch_after(delayInNanoSeconds, concurrentQueue, ^(void){ /* Perform your operations here */
}); 

Performing a Task Only Once with GCD
use the dispatch_once function


Friday, July 19, 2013

Core Data Programming Guide Notes -- Part 6

This is the notes of Core Data Programing Guide from reading Apple's document

reference: http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html#//apple_ref/doc/uid/TP30001200-SW1


Core Data FAQ
Where does a Managed Object Context Come From? 

Where a managed object context comes from is entirely application-dependent. In a Cocoa document-based application using NSPersistentDocument, the persistent document typically creates the context, and gives you access to it through the managedObjectContext method. 



How do I initialize a store with default data? 

There are two issues here: creating the data, and ensuring the data is imported only once.

There are several ways to create the data.

  • You can create a separate persistent store that contains the default data and include the store as an application resource. When you want to use it, you must either copy the whole store to a suitable location, or copy the objects from the defaults store to an existing store.
  • For small datasets, you can create the managed objects directly in code.
  • You can create a property list—or some other file-based representation—of the data, and store it as an application resource. When you want to use it, you must open the file and parse the representation to create managed objects. 

How do I use my existing SQLite database with Core Data?

You don’t. Although Core Data supports SQLite as one of its persistent store types, the database format is private. You cannot create a SQLite database using native SQLite API and use it directly with Core Data (nor should you manipulate an existing Core Data SQLite store using native SQLite API). If you have an existing SQLite database, you need to import it into a Core Data store


 How do I fetch objects in the same order I created them?
 Objects in a persistent store are unordered. Typically you should impose order at the controller or view layer, based on an attribute such as creation date. If there is order inherent in your data, you need to explicitly model that.
 






Core Data Programming Guide Notes -- Part 5

This is the notes of Core Data Programing Guide from reading Apple's document




Concurrency with Core Data

You can use threads, serial operation queues, or dispatch queues for concurrency. For the sake of conciseness, this article uses “thread” throughout to refer to any of these.

Use Thread Confinement to Support Concurrency 
The pattern recommended for concurrent programming with Core Data is thread confinement : each thread must have its own entirely private managed object context. 

There are two possible ways to adopt the pattern:
  1. Create a separate managed object context for each thread and share a single persistent store coordinator.
    This is the typically-recommended approach. 
      2.Create a separate managed object context and persistent store coordinator for each thread.
         This approach provides for greater concurrency at the expense of greater complexity (particularly            if you need to communicate changes between different contexts) and increased memory usage. 

You must create the managed context on the thread on which it will be used. If you use NSOperation, note that its init method is invoked on the same thread as the caller. You must not, therefore, create a managed object context for the queue in the queue’s init method, otherwise it is associated with the caller’s thread. Instead, you should create the context in main (for a serial queue) or start (for a concurrent queue).

Using thread confinement, you should not pass managed objects or managed object contexts between threads. To “pass” a managed object from one context another across thread boundaries, you either:

  •  Pass its object ID (objectID) and use objectWithID: or existingObjectWithID:error: on the receiving managed object context. 

          The corresponding managed objects must have been saved—you cannot pass the ID of a newly-             inserted managed object to another context. 

  •  Execute a fetch on the receiving context.


Track Changes in Other Threads Using Notifications


Typically, on thread A you register for the managed object context save notification, NSManagedObjectContextDidSaveNotification. When you receive the notification, its user info dictionary contains arrays with the managed objects that were inserted, deleted, and updated on thread B. Because the managed objects are associated with a different thread, however, you should not access them directly. Instead, you pass the notification as an argument to mergeChangesFromContextDidSaveNotification: (which you send to the context on thread A). Using this method, the context is able to safely merge the changes. 


Fetch in the Background for UI Responsiveness 

Following the thread confinement pattern, you use two managed object contexts associated with a single persistent store coordinator. You fetch in one managed object context on a background thread, and pass the object IDs of the fetched objects to another thread. In the second thread (typically the application's main thread, so that you can then display the results), you use the second context to fault in objects with those object IDs (you use objectWithID: to instantiate the object). (This technique is only useful if you are using an SQLite store, since data from binary and XML stores is read into memory immediately on open.)


Saving in a Background Thread is Error-prone

If you perform a save operation in a background thread, therefore, it may be killed before it is able to complete. If you need to save on a background thread, you must write additional code such that the main thread prevents the application from quitting until all the save operation is complete. 

If You Don’t Use Thread Containment
If you choose not to use the thread containment pattern—that is, if you try to pass managed objects or contexts between threads, and so on—you must be extremely careful about locking, and as a consequence you are likely to negate any benefit you may otherwise derive from multi-threading. You also need to consider that:

  • Any time you manipulate or access managed objects, you use the associated managed object context. Core Data does not present a situation where reads are “safe” but changes are “dangerous”—every operation is “dangerous” because every operation has cache coherency effects and can trigger faulting. 
  • Managed objects themselves are not thread safe. If you want to work with a managed object across different threads, you must lock its context (seeNSLocking). 

Typically you lock the context or coordinator using tryLock or lock. If you do this, the framework will ensure that what it does behind the scenes is also thread-safe. For example, if you create one context per thread, but all pointing to the same persistent store coordinator, Core Data takes care of accessing the coordinator in a thread-safe way (the lock and unlock methods of NSManagedObjectContext handle recursion).
If you lock (or successfully tryLock) a context, you must keep a strong reference to that context until you invoke unlock. If you don’t, in a multi-threaded environment, you may cause a deadlock. 



Core Data Performance

Fetching Managed Objects 
 Fetch Predicates
 How you use predicates can significantly affect the performance of your application.
 Especially if the predicate involves text matching (contains, endsWith, like, and matches) since correct Unicode searching is slow. If the predicate combines textual and non-textual comparisons, then it is likely to be more efficient to specify the non-textual predicates first, for example (salary > 5000000) AND (lastName LIKE 'Quincey') is better than (lastName LIKE 'Quincey') AND (salary > 5000000).
 


Fetch Limits

You can set a limit to the number of objects a fetch will return using the method setFetchLimit: as shown in the following example.

NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setFetchLimit:100];

Faulting Behavior
You can safely invoke the following methods on a fault without causing it to fire: isEqual:, hash, superclass, class, self, zone, isProxy, isKindOfClass:, isMemberOfClass:, conformsToProtocol:, respondsToSelector:, description, managedObjectContext, entity, objectID, isInserted, isUpdated, isDeleted, and isFault. 

Batch Faulting and Pre-fetching with the SQLite Store

When you execute a fetch, Core Data fetches just instances of the entity you specify. 


Analyzing Performance 

Analyzing Fetch Behavior with SQLite
With OS X version 10.4.3 and later, you can use the user default com.apple.CoreData.SQLDebug to log to stderr the actual SQL sent to SQLite. (Note that user default names are case sensitive.) For example, you can pass the following as an argument to the application:

-com.apple.CoreData.SQLDebug 1

 






Troubleshooting Core Data

Object Life-Cycle Problems 

Merge errors 

Problem: You see the error message, "Could not merge changes".
Cause: Two different managed object contexts tried to change the same data. This is also known as an optimistic
locking failure.
Remedy: Either set a merge policy on the context, or manually (programmatically) resolve the failure. You can retrieve the currently committed values for an object using committedValuesForKeys:, and you can re-fault the object (so that when it is next accessed its data values are retrieved from its persistent store) using refreshObject:mergeChanges:.


Assigning a managed object to a different store 
Problem: You see an exception that looks similar to this example. 
  [_assignObject:toPersistentStore:]:
Can’t reassign an object to a different store once it has been saved.
Cause: The object you are trying to assign to a store has already been assigned and saved to a different store. Remedy: To move an object from one store to another, you must create a new instance, copy the information
from the old object, save it to the appropriate store, and then delete the old instance.
Fault cannot be fulfilled
Problem: You see the error message, "Core Data could not fulfill a fault". Cause: The corresponding object's underlying data has been deleted from the persistent store. Remedy: You should discard this object. This problem can occur in at least two situations:
First:
Start with a strong reference to a managed object.
Delete the managed object via the managed object context.
Save changes on the object context.
At this point, the deleted object has been turned into a fault. It isn’t destroyed because doing so would violate the rules of memory management.
Try to retrieve an attribute or relationship from the previously retained reference.
Core Data will try to fault the faulted managed object but will fail to do so because the object has been deleted from the store. That is, there is no longer an object with the same global ID in the store.
Second:
Delete an object from a managed object context. Fail to break all relationships from other objects to that object. Save changes.
Managed object invalidated
Problem: You see an exception that looks similar to this example:
[_assignObject:toPersistentStore:]: The NSManagedObject with ID:#### has been invalidated.
Cause: Either you have removed the store for the fault you are attempting to fire, or the managed object's context has been sent a reset message.
Remedy: You should discard this object. If you add the store again, you can try to fetch the object again.
Class is not key-value coding compliant
Problem: You see an exception that looks similar to the following example.
 [ valueForUndefinedKey:]:
this class is not key value coding-compliant for the key randomKey.
Cause: Either you used an incorrect key, or you initialized your managed object with init instead of initWithEntity:inManagedObjectContext:.
Remedy: Use a valid key (check the spelling and case carefully—also review the rules for key-value coding compliance in Key-Value Coding Programming Guide ), or ensure that you use the designated initializer for NSManagedObject (see initWithEntity:insertIntoManagedObjectContext:).
Efficiently Importing Data

Cocoa Fundamentals

Thursday, July 18, 2013

Core Data Programming Guide Notes -- Part 4

This is the notes of Core Data Programing Guide from reading Apple's document

reference: http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html#//apple_ref/doc/uid/TP30001200-SW1


Using Persistent Stores
 Creating and Accessing a Store
 Access to stores is mediated by an instance of NSPersistentStoreCoordinator. You should not need to directly access a file containing a store. From a persistent store coordinator, you can retrieve an object that represents a particular store on disk. Core Data provides an NSPersistentStore class to represent persistent stores.
 

To retrieve a store object from a coordinator, you use the method persistentStoreForURL:. You can use a store to restrict a fetch request to a specific store, as shown in the following code fragment:







Core Data and Cocoa Bindings

Note that Cocoa bindings are not available on iOS. 


Change Management

Conflict Detection and Optimistic Locking 
When Core Data fetches an object from a persistent store, it takes a snapshot of its state. A snapshot is a dictionary of an object’s persistent properties—typically all its attributes and the global IDs of any objects to which it has a to-one relationship. 


If the values are the same, then the store has not been changed since the object was fetched, so the save proceeds normally. As part of the save operation, the snapshots' values are updated to match the saved data.

If the values differ, then the store has been changed since the object was fetched or last saved; this represents an optimistic locking failure. 


Conflict Resolution

You can get an optimistic locking failure if more than one persistence stack references the same external data store (whether you have multiple persistence stacks in a single application or you have multiple applications). 


The default behavior is defined by the NSErrorMergePolicy. This policy causes a save to fail if there are any merge conflicts. 


In the case of failure, the save method returns with an error with a userInfo dictionary that contains the key @"conflictList"


The NSErrorMergePolicy is the only policy that generates an error. Other policies—NSMergeByPropertyStoreTrumpMergePolicy, NSMergeByPropertyObjectTrumpMergePolicy, and NSOverwriteMergePolicy—allow the save to proceed by merging the state of the edited objects with the state of the objects in the store in different ways. The NSRollbackMergePolicy discards in-memory state changes for objects in conflict and uses the persistent store’s version of the objects’ state.

Snapshot Management
An application that fetches hundreds of rows of data can build up a large cache of snapshots. 

Responsibility for cleaning up snapshots rests with a mechanism called snapshot reference counting


Communicating Changes Between Contexts
The following three strategies are presented in order of increasing complexity.

1.The simplest case is when the object itself has not changed in moc2 and you do not have to worry about undo; in this situation, you can just delete the object. The next time moc2 saves, the framework will notice that you are trying to re-delete an object, ignore the optimistic locking warning, and continue without error. 

2.If you do not care about the contents of moc2, you can simply reset it (using reset) and refetch any data you need after the reset. This will reset the undo stack as well, and the deleted object is now gone. The only issue here is determining what data to refetch. You can do this by, before you reset, collecting the IDs (objectID) of the managed objects you still need and using those to reload once the reset has happened (you must exclude the deleted IDs, and it is best to create fetch requests with IN predicates to avoid problems will not being able to fulfill faults for deleted IDs). 
3. If the object has changed in moc2, but you do not care about undo, your strategy depends on what it means for the semantics of your application. If the object that was deleted in moc1 has changes in moc2, should it be deleted from moc2 as well? Or should it be resurrected and the changes saved? What happens if the original deletion triggered a cascade delete for objects that have not been faulted into moc2? What if the object was deleted as part of a cascade delete?
There are two workable options (a third, unsatisfactory option is described later):
  1. The simplest strategy is to just discard the changes by deleting the object.
Alternatively, if the object is standalone, you can set the merge policy on the context to NSMergePolicyOverwrite. This will cause the changes in the second context to overwrite the delete in the database.
Note that this will cause all changes in moc2 to overwrite any changes made in moc1



Persistent Store Features
Store Types and Behaviors
Core Data provides three sorts of disk-based persistent store—XML, atomic, and SQLite—and an in-memory store. 
iOS: The XML store is not available on iOS. 
  
File Size May Not Reduce After Deleting a Record


Core Data Programming Guide Notes -- Part 3

This is the notes of Core Data Programing Guide from reading Apple's document

reference: http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html#//apple_ref/doc/uid/TP30001200-SW1



Object Lifetime Management 

The Role of the Managed Object Context 

his means that in general you cannot rely on a context to ensure the longevity of a managed object instance, and you cannot rely on the existence of a managed object to ensure the longevity of a context.


The exception to this rule is that a managed object context maintains a strong reference to any changed (inserted, deleted, and updated) objects until the pending transaction is committed (with a save:) or discarded (with a reset or rollback). 

 If you have finished with a managed object context, or for some other reason you want to “disconnect” a context from its persistent store coordinator, you should not set the context’s coordinator to nil:

// This will raise an exception
[myManagedObjectContext setPersistentStoreCoordinator:nil];


Instead, you should simply relinquish ownership of the context and allow it to be deallocated normally. 


Breaking Relationship Strong Reference Cycles

To ensure that reference cycles are broken, when you're finished with an object you can use the managed object context method refreshObject:mergeChanges: to turn it into a fault.

Change and Undo Management

A context keeps strong references to managed objects that have pending changes (insertions, deletions, or updates) until the context is sent a save:, reset , rollback, or dealloc message, or the appropriate number of undos to undo the change. 

The undo manager associated with a context keeps strong references to any changed managed objects.




Relationships and Fetched Properties

Core Data does not let you create relationships that cross stores. If you need to create a relationship from objects in one store to objects in another, you should consider using fetched properties.


Relationship Fundamentals

A relationship specifies the entity, or the parent entity, of the objects at the destination. This can be the same as the entity at the source (a reflexive relationship).

You can specify a relationship as being to-one or to-many. To-one relationships are represented by a reference to the destination object. To-many relationships are represented by mutable sets (although fetched properties are represented by arrays). Implicitly, “to-one” and “to-many” typically refer to “one-to-one” and “one-to-many” relationships respectively. A many-to-many relationship is one where a relationship and its inverse are both to-many.


You can also put upper and lower limits on the number of objects at the destination of a to-many relationship. The lower limit does not have to be zero. You can if you want specify that the number of employees in a department must lie between 3 and 40. You also specify a relationship as either optional or not optional. If a relationship is not optional, then in order to be valid there must be an object or objects at the destination of the relationship.

Relationship Delete Rules
A relationship's delete rule specifies what should happen if an attempt is made to delete the source object.


Deny
If there is at least one object at the relationship destination, then the source object cannot be deleted.
For example, if you want to remove a department, you must ensure that all the employees in that department are first transferred elsewhere (or fired!) otherwise the department cannot be deleted.


Nullify
Set the inverse relationship for objects at the destination to null.
For example, if you delete a department, set the department for all the current members to null. This only makes sense if the department relationship for an employee is optional, or if you ensure that you set a new department for each of the employees before the next save operation.


Cascade
Delete the objects at the destination of the relationship.
For example, if you delete a department, fire all the employees in that department at the same time.


No Action
Do nothing to the object at the destination of the relationship.
For example, if you delete a department, leave all the employees as they are, even if they still believe they belong to that department.

Manipulating Relationships and Object Graph Integrity

anEmployee.department = newDepartment;
Alternatively, you can use:
[newDepartment addEmployeeObject:anEmployee];

Many-to-Many Relationships 
  
You must define many-to-many relationships in both directions—that is,you must specify two relationships, each being the inverse of the other. You can’t just define a to-many relationship in one direction and try to use it as a many-to-many. If you do, you will end up with referential integrity problems.



Unidirectional Relationships

in general, you should avoid using unidirectional relationships. Bidirectional relationships provide the framework with additional information with which to better maintain the object graph. If you do want to use unidirectional relationships, you need to do some of this maintenance yourself. In the case above, this would mean that after this line of code:

[managedObjectContext deleteObject:department]; 
 you should write:
[employee setValue:nil forKey:@"department"];


 Cross-Store Relationships
You must be careful not to create relationships from instances in one persistent store to instances in another persistent store, as this is not supported by Core Data. If you need to create a relationship between entities in different stores, you typically use fetched properties.


Fetched Properties
Fetched properties represent weak, one-way relationships. 
A fetched property is like a relationship, but it differs in several important ways:

  •  Rather than being a "direct" relationship, a fetched property's value is calculated using a fetch request. (The fetch request typically uses a predicate to constrain the result.) 
  • A fetched property is represented by an array, not a set. The fetch request associated with the property can have a sort ordering, and thus the fetched property may be ordered. 
  • A fetched property is evaluated lazily, and is subsequently cached.

You use refreshObject:mergeChanges: to manually refresh the properties—this causes the fetch request associated with this property to be executed again when the object fault is next fired. 
 There are two special variables you can use in the predicate of a fetched property—$FETCH_SOURCE and $FETCHED_PROPERTY.



Non-Standard Persistent Attributes 

he principle behind the two approaches is the same: you present to consumers of your entity an attribute of the type you want, and “behind the scenes” it’s converted into a type that Core Data can manage. 


Transformable Attributes



Managed Object Validation

There are two types of validation—property-level and inter-property. You use property-level validation to ensure the correctness of individual values; you use inter-property validation to ensure the correctness of combinations of values.

Core Data Validation
Cocoa provides a basic infrastructure for model value validation. It requires you, though, to write code for all the constraints you want to apply. Core Data allows you to put validation logic into the managed object model.

If you do want to customize validation of individual properties, you use standard validation methods as defined by the NSKeyValueCoding protocol 

Property-Level Validation 


The NSKeyValueCoding protocol specifies a method—validateValue:forKey:error:—that provides general support for validation methods in a similar way to that in which valueForKey: provides support for accessor methods. 


If you want to implement logic in addition to the constraints you provide in the managed object model, you should not override validateValue:forKey:error:. Instead you should implement methods of the form validate:error:


If you do implement custom validation methods, you should typically not invoke them directly. Instead you should call validateValue:forKey:error: with the appropriate key. This ensures that any constraints defined in the managed object model are also applied. 
-(BOOL)validateAge:(id*)ioValue error:(NSError **)outError{}


The input value is a pointer to object reference (an id *). This means that in principle you can change the input value 

Inter-Property validation
NSManagedObject provides additional loci for validation—update, insertion, and deletion—through the validateFor... methods such as validateForUpdate:. 



Combining Validation Errors



Faulting and Uniquing

Faulting is a mechanism Core Data employs to reduce your application’s memory usage. 
Faulting Limits the Size of the Object Graph

A fault is a placeholder object that represents a managed object that has not yet been fully realized, or a collection object that represents a relationship: 

1. A managed object fault is an instance of the appropriate class, but its persistent variables are not yet initialized.
2. A relationship fault is a subclass of the collection class that represents the relationship. 


To illustrate, consider an application that allows a user to fetch and edit details about a single employee. The employee has a relationship to a manager and to a department, and these objects in turn have other relationships. If you retrieve just a single Employee object from a persistent store, its manager, department, and reports relationships are initially represented by faults. Figure 1 shows an employee’s department relationship represented by a fault.




Fault handling is transparent—you do not have to execute a fetch to realize a fault.


If at some stage a persistent property of a fault object is accessed, then Core Data automatically retrieves the data for the object and initializes the object.

Firing Faults 


Turning Objects into Faults 

Turning a realized object into a fault can be useful in pruning the object graph.

Turning a managed object into a fault releases unnecessary memory, sets its in-memory property values to nil, and breaks strong references to related objects.

You can turn a realized object into a fault with the refreshObject:mergeChanges: method. If you pass NO as the mergeChanges argument, you must be sure that there are no changes to that object’s relationships.

When an object turns into a fault, it is sent a didTurnIntoFault message. You may implement a custom didTurnIntoFault method to perform various “housekeeping” function

Uniquing Ensures a Single Managed Object per Record per Context

Core Data ensures that—in a given managed object context—an entry in a persistent store is associated with only one managed object. The technique is known as uniquing.  


For example, consider the situation illustrated in Figure 2; two employees have been fetched into a single managed object context . Each has a relationship to a department, but the department is currently represented by a fault.



It would appear that each employee has a separate department, and if you asked each employee for their department in turn—turning the faults into regular objects—you would have two separate Department objects in memory. However, if both employees belong to the same department (for example, "Marketing"), then Core Data ensures that (in a given managed object context) only one object representing the Marketing department is ever created. If both employees belong to the same department, their department relationships would both therefore reference the same fault