by Christian Keur, Aaron Hillegass, and Joe Conway
- The lefthand side of Xcode shows the navigator area.
- XIB stands for XML Interface Builder. It is pronounced "zib". You create and configure objects, and then save them into an archive, or the XIB file.
- In Interface Builder, the utility area is to the right of the editor. It is divided into the inspector and library sections.
- XIB files are complied into NIB files that are smaller and easier for the application to parse. That is copied into the application's bundle.
- A connection allows two objects to communicate. There are two kinds: An outlet points to an object, while an action defines a callback.
- Select the File's Owner object, and then the connections inspector to view all wired outlets and actions.
- The App Delegate manages the single top-level
UIWindow
. Assign itswindow.rootViewController
to specify the starting view controller. - The App ID in you provisioning profile must match the bundle identifier of your application. But a development profile can use an App ID of
*
and match any bundle identifier. - The provisioning profile refers to a developer certificate, a single App ID, and a list of device IDs that the application can be installed on.
- The developer certificate is on your Mac's keychain. The provisioning profile belongs to your development device and your computer.
- When deploying to the App Store, an application must have an icon for every device class on which it can run.
- The
Images.xcassets
file contains anAppIcon
section where you can place the various icons for your application. - A good launch image is a content-less screenshot of the application. Although not required, you can provide one for each class of device.
- In Objective-C, we typically put an underscore at the beginning of an instance variable, or ivar, name.
- A method is a chunk of code to be executed, while a message is the act of acting a class or object to execute a method.
- A message sent to
nil
is ignored. So if your program is not doing anything when you expect something, an unexpectednil
is usually the culprit. - Perform fast iteration over an array while attempting to add or remove objects will cause an exception to be thrown.
- In Objective-C, the name of a getter method is just the name of the instance variable that it returns.
- Use accessor methods to access instance variables, even inside a class. Do not refer to them by name, which is prefaced with an underscore.
- All initializers of a class call its designated initializer, which in turn calls the designated initializer of the superclass.
- The
instancetype
keyword can only be used for return types, and matches the return type of the receiver.init
methods always returninstancetype
. - In Objective-C, class methods that return an object of their type (like
stringWithFormat
) are called convenience methods. - You can use
array[index]
as shorthand forobjectAtIndex:
,insertObject:atIndex:
, andreplaceObjectAtIndex:withObject:
. - Objective-C has no notion of namespaces. Prefix class names with three letters to keep them distinct. Two-letter prefixes are reserved by Apple.
- Precompiled header files saves us from parsing and compiling standard headers repeatedly, but Apple will eventually replace them with the
@import
directive.
- A variable that does not take ownership of an object is called a weak reference. This helps avoid a strong reference cycle, or retain cycle.
- To decide what reference in a cycle should be weak, look for a parent-child relationship. A parent should own its child, but a child should never own its parent.
- Preface the instance variable declaration with
__weak
to convert it to a weak reference. - A weak reference knows when the object that it points to is destroyed, and responds by setting itself to
nil
. This avoids a dangling pointer. - When using
@property
, the name of the generated instance variable is prefixed by an underscore. - By default, properties are declared
atomic
,readwrite
, andstrong
. We explicitly declare thestrong
attribute, in case a new default attribute value is chosen later. - When a property points to an instance of a class that has a mutable subclass, you should set its memory management attribute to
copy
. - To prevent needless copying, immutable classes implement
copy
to quietly return a pointer to the original and immutable object. - If you implement a custom setter and a custom getter on a
readwrite
property, or a custom getter on areadonly
property, then you must declare your own instance variable. - You can use this technique to define accessor methods that are not backed by any instance variable, or backed by some property of a contained object.
- ARC was born when the Clang static analyzer became so good that it could insert all the
retain
andrelease
messages automatically. - Inside an
@autoreleasepool
directive, any newly instantiated object returned from a method that does not havealloc
orcopy
in its name is put into an autorelease pool.
- Each view draws itself by rendering itself to a layer, which is an instance of
CALayer
. These layers are then composited together on the screen. - The
x
andy
ofCGPoint
andwidth
andheight
ofCGRect
are specified in points, not pixels, so they are consistent across different resolutions. - A pixel is equal to half a point on Retina, and equal to one point on non-retina. When printing to paper, an inch is 72 points long.
- The
drawRect:
method renders the view onto its layer.UIView
subclasses override this method to perform custom drawing. - The
bounds
rectangle is in the view's own coordinate system, for drawing itself. Theframe
rectangle is in the superview's coordinate system, for positioning the subview. - Instances of
UIBezierPath
define and draw lines and curves that you can use to make shapes. - To set the color drawn by the
stroke
method ofUIBezierPath
, send the messagesetStroke
of aUIColor
instance. CGContextRef
is the graphics context, which holds the drawing properties (like the pen color and line thickness) and the memory that is being drawn upon.- The system creates a
CGContextRef
instance before callingdrawRect:
, and composites that instance after the method completes executing. - The current context is an application-wide pointer that is assigned just before
drawRect:
is called. You can retrieve it by callingUIGraphicsGetCurrentContext()
. - A Core Graphics type ending in
Ref
is a pointer typedef. If you create such an object with a function that hasCreate
orCopy
in the name, then you must pass it to the matchingRelease
function. - Some Core Graphic features cannot be "unset." Instead, you must pass
currentContext
toCGContextSaveGState
beforehand, and then toCGContextRestoreGState
afterward.
- When the user touches a view, it is sent the message
touchesBegan:withEvent:
. - After the run loop dispatches an event, it invokes
drawRect:
on all dirty views. Send the messagesetNeedsDisplay
to a view to mark it as dirty. - If you call
setNeedsDisplayInRect:
instead, thatCGRect
method is passed todrawRect:
, which you can use to optimize re-drawing. But most developers don't bother with this. - The
contentSize
of aUIScrollView
is the size of the area that it can be used to view. This is usually the size of its subview. - After adding multiple subviews to a
UIScrollView
, you can set itspagingEnabled
property to page between them, which snaps its viewing port to a subview.
- A view controller's
view
is not created until it needs to appear on screen. - When a view controller initializes its view hierarchy from a NIB file, you do not override
loadView
. The default implementation loads the NIB file. - Declare outlets as
weak
. This ensures that, when memory is low, destroyingview
also destroys its subviews and avoids memory leaks. - When a view controller is contained by a
UITabBarController
, itstabBarItem
property appears in the tab bar for that purpose. - Calling
init
calls the designated initializerinitWithNibName:bundle:
. It looks for a NIB with the class name in the main bundle, which it specifies by passingnil
as the bundle. - To preserve the benefits of lazy loading, you should never access the
view
property of a view controller ininitWithNibName:bundle:
. - Destroying and reloading the view of a view controller due to memory constraints is not the typical behavior on newer devices.
- When calling
valueForKey:
, key-value coding will first look for a corresponding getter method, followed by an instance variable. - Retina display is 640x1136 pixels on a 4" display, and 640x960 pixels on a 3.5" display, while earlier devices have a display of 320x480 pixels.
- By appending the suffix
@2x
to a higher resolution image, methodimageNamed:
ofUIImage
loads the file that is appropriate for the particular device.
UIResponder
is an abstract class that defines methods for handling events, such as touch events, motion events, and remote control events.- Touch events are sent directly to the corresponding view. For other event types,
UIWindow
has afirstResponder
pointer that specifies their handler. - Text fields and text views show and hide the keyboard upon becoming and resigning the first responder. Most views refuse to become the first responder so that they do not steal focus.
- By default, protocol methods are required, but you can precede a list of optional methods with the directive
@optional
. - If a method in a protocol is required, then a message will be sent to it without first creating a
SEL
instance and sending messagerespondsToSelector:
. - You can declare that an object conforms to a protocol in the private extension of that class, as opposed to in its header file.
- A class that uses a delegate must declare it as a weak reference in order to prevent strong reference cycles.
- The
textFieldShouldReturn:
method must explicitly dismiss the keyboard by sending the messageresignFirstResponder
to the text field. - If your application is throwing exceptions and you're not sure why, adding an exception breakpoint will help you pinpoint what's going on.
- The
UIApplicationMain
method creates an instance ofUIApplication
, which maintains the run loop. - Next,
UIApplicationMain
creates an instance of the delegate class, assigns it todelegate
of theUIApplication
instance, and sends a message toapplication:didFinishLaunchingWithOptions:
.
- The designated initializer of
UITableViewController
isinitWithStyle:
. - To return a read-only view of an
NSMutableArray
, define a privateNSMutableArray
property, and then define anNSArray
property with thereadonly
attribute that returns it. - The
contentView
of aUITableViewCell
contains the three subviewstextLabel
,detailTextLabel
, andimageView
. - Call the
registerClass:forCellReuseIdentifier:
ofUITableView
to specify which kind of cell it should instantiate if there are no cells with a given identifier in the reuse pool. - To define a placeholder in a code snippet from the library, place its name between
<#
and#>
.
- The
strong
attribute must be used with properties that reference top-level objects in the XIB file. - To resize an empty view in Interface Builder, go to the Simulated Metrics section, and select None for the Size option.
- To load a NIB file manually, send
loadNibNamed:owner:options:
toNSBundle
, where the owner is substituted for the File's Owner placeholder. - A
UITableViewController
automatically sets theediting
property of its table view to match its ownediting
property. - To add a cell, a button above the cells of the table view is usually for adding a record for which there is a detail view.
- To add a cell, a cell with a green plus sign is usually for adding a new field to a record.
- The
view
andtableView
properties ofUITableViewController
refer to the same view. - When you implement
tableView:commitEditingStyle:forRowAtIndexPath:
, swipe-to-delete also works automatically. - In the call to
tableView:moveRowAtIndexPath:toIndexPath:
, the row of the new path is that after the item has been removed from its existing path. - In editing mode, the
UITableView
will not display the reordering controls if its data source does not implementtableView:moveRowAtIndexPath:toIndexPath:
.
- The view of a
UINavigationController
always has two subviews: aUINavigationBar
and the view belonging to thetopViewController
. - A
UINavigationController
will automatically resize the view of aUIViewController
on its stack so that it fits below the navigation bar. - Do not position subviews near the top of a XIB file. A view will extend beneath either a
UINavigationBar
or beneath aUITabBar
. - If you display an
.m
file next to its XIB file using the assistant editor, you can Control-drag views from the XIB to the.m
file to automatically create outlets. - The shortcut Command-T opens up a new tab, while Command-Shift-} and Command-Shift-{ cycle through the tabs.
- When the message
endEditing:
is sent to a view, if it or any of its subviews is the first responder, it will resign its first responder status and dismiss the keyboard. - Every
UIViewController
has anavigationItem
property that supplies the navigation bar with the content that it needs to draw. - For the
titleView
of aUINavigationItem
, you can either use a basic string as the title or specify aUIView
instance. UIViewController
has aneditButtonItem
property that is of typeUIBarButtonItem
. When pressed, it sends the messagesetEditing:animated:
to the controller.
- The
contentMode
property ofUIImageView
determines where to position and how to resize the content of its frame. - You cannot use
UIImagePickerControllerSourceTypeCamera
on devices without cameras, and must sendisSourceTypeAvailable:
toUIImagePickerController
first. - To populate the photo library in the simulator, open Safari in the simulator, navigate to a page with an image, and save the image.
- Objects of type
NSUUID
represent a UUID and are generated using the time, a counter, and a hardware identifier, which is usually the MAC address from the WiFi device. - While a
UIBarButtonItem
only sends its target an action message when it is pressed,UIControl
can send messages in response to a variety of events. - With the
#pragma mark
directive, you can specify just a divider with-
, a label, or both by prefacing the label with-
. - Just like the class method
isSourceTypeAvailable:
returns whether a device has a camera,availableMediaTypesForSourceType:
returns whether it can capture video. - After the user takes a video,
imagePickerController:didFinishPickingMediaWithInfo:
is passed the path to the video in a temporary directory.
- If a finger moves outside the frame of the
UIView
that it began on, that view still receivestouchesMoved:withEvent:
andtouchesEnded:withEvent
messages. - While the methods of
UIResponder
accept a set ofUITouch
instances, there are usually multiple responder methods with one or more touches. - Once a touch begins, a
UIResponder
will ignore subsequent touches unless itsmultipleTouchesEnabled
property is set. - You can simulate touching with multiple fingers in the simulator by holding down the Option key as you drag.
- The
valueWithNonretainedObject:
method ofNSValue
is useful if you want to add an object to a collection without creating a strong reference to it. - This method also allows objects that do not implement
NSCopying
to be used as keys in dictionaries. - Every
UIResponder
, such asUIView
,UIViewController
,UIWindow
, andUIApplication
, has a pointer callednextResponder
, forming a responder chain. - By default, methods
touchesBegin:withEvent:
,touchesMoved:withEvent:
, andtouchesEnded:withEvent
simply delegate tonextResponder
. - The
CGRectContainsPoint
method returns whether a given point is in aCGRect
variable.
- A
UIGestureRecognizer
intercepts touches destined for a view, and so this view may not respond to typicalUIResponder
messages. - Setting the
delaysTouchesBegan
property delays sendingtouchesBegan:withEvent:
to its view if it is still possible for the gesture to be recognized. - The method
requireGestureRecognizerToFail:
allows you to require a double-tap recognizer to fail before invoking a single-tap recognizer. - The
locationInView:
method ofUIGestureRecognizer
returns the coordinate where the gesture occurred in the coordinate system of its view argument. - For a
UIMenuController
to appear, a view that responds to at least one action message of its menu items must be a first responder of the window. - If you have a custom view that needs to become the first responder, you must implement
canBecomeFirstResponder
to returnYES
. - A long press gesture begins when the user holds a touch for 0.5 seconds, and ends when the touch ends.
- A gesture recognizer will send
gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
to itsdelegate
if another gesture recognizer has recognized its gesture, too. - The
translationInView:
method ofUIPanGestureRecognizer
returns aCGPoint
containing how far the pan has moved in the coordinate system of its view argument. - Pass
CGPointZero
tosetTranslation:inView:
ofUIPanGestureRecognizer
at the end of its action method to report the change in translation between action method calls. - If a
UIResponder
implements a method inUIResponderStandardEditActions
, it enables the corresponding default menu item in an unmodified menu controller. - A
UIGestureRecognizer
for a discrete gesture like tap only enters the recognized state; it does not transition through the begin, change, and end states. - A gesture recognizer can enter the fail state, such as when no amount of finger contortion can make the particular gesture, given their current position.
- The debug gauges in Xcode are based on the hardware running the simulator, which is undoubtedly more powerful than the iOS device.
- In the Memory Report, the Memory graph scales so that peak usage represents 100%.
- In the Allocations instrument, the # Overall column shows you how many instances of a class have been allocated -- even if they have since been deallocated.
- When you select a method, the percentage on each line of the method specifies the amount of memory that line allocates compared to the other lines.
- The Generation Analysis category, also called Heapshot Analysis, is very useful for inspecting what objects get allocated for a specific event.
- By choosing Invert Call Tree in the Time Profiler, you can see how much time is spent in each method call.
- If a system call takes a lot of time, you can change it so that the time spent in that method is attributed to the method that called it.
- The
mach_msg_trap()
method is where the main thread sits when waiting for input, and so it is not a bad thing to spend time in this function. CGPoint
andCGRect
are structures instead of Objective-C classes so they do not incur the overhead of sending messages for simple operations.- A project has at least one target. You build and run the target, which produces a product, such as the application, a library, or a unit test bundle.
- Under Build Settings, setting Analyze During 'Build' will automatically run the static analyzer every time you build your application.
- A single application that runs natively on both the iPhone and the iPad is called a universal application.
- The iPhone 4S has 320x480 points, the iPhone 5 and later has 320x568 points, and all iPads have 768x1024 points.
- Constraints determine the layout attributes like the size, margins, center, and baseline of the alignment rectangle constructed by Auto Layout.
- The nearest neighbor of a view is the closest sibling view in a specified direction, or its superview if no such sibling view exists.
- Apple recommends that you add constraints using Interface Builder whenever possible, instead of defining them programmatically.
- Constraint problems include missing constraints, conflicting constraints, and constraints not matching a view's size and position on the canvas.
- By Control-dragging from one view to another on the canvas, you can specify a constraint between those views.
- Constraints have a priority value ranging from
1
to1000
, where1000
is a required constraint. This is their default value. - To remedy an ambiguous layout, which occurs when there is more than one way to fulfill a set of constraints, add another constraint.
- To display an alternate layout resulting from ambiguous constraints, send the message
exerciseAmbiguityInLayout
to each subview. - A misplaced view problem is when a view's frame in a XIB does not match its constraints.
- For a string representation of the view hierarchy, with views having ambiguous layout tagged, set a breakpoint and then enter into the debugger
po [[ UIWindow keyWindow] _autolayoutTrace]
. - If you need completely different views depending on the device, create one XIB file with a
~iphone
suffix, and another with an~ipad
suffix.
- If creating and constraining an additional view to add to a view hierarchy that was created by loading a NIB file, override method
viewDidLoad
. - Without setting
translatesAutoresizingMaskIntoConstraints
toNO
, iOS creates constraints from the mask, which may conflict with other constraints. - In the Visual Format Language, or VFL, the dash by itself sets the spacing to the standard number of points between views, which is 8.
- You should call
addConstraints:
on the closest common ancestor of all the views that are affected by the constraint. - Unlike other constraints, intrinsic content size constraints have a content hugging priority and a content compression resistance priority.
- A content hugging priority of
1000
means that the view should never be allowed to grow larger than its intrinsic content size. - A content compression resistance priority of
1000
means that the view should never be allowed to be smaller than its intrinsic content size. - Before Auto Layout, each view had a resizing mask that constrained the relationship between a view and its superview.
- When debugging constraints, a constraint from the resizing mask has the type
NSAutoResizingMaskLayoutConstraint
instead ofNSLayoutConstraint
.
- Device orientation represents the physical orientation of the device. You can access it through the
orientation
property ofUIDevice
. - The interface orientation is a property of the running application, and is determined by the location of the Home button.
- For the interface orientation to change, both the
rootViewController
of the application and the application itself must allow the new orientation. - To match convention, a view controller on the iPad allows all four orientations, while one on the iPhone allows any orientation other than upside-down.
- A
UITabViewController
only supports an orientation if the view controllers for each of its tabs support it. - The
statusBarOrientation
method of theUIApplication
instance returns the interface orientation. - Trying to instantiate
UIPopoverController
on anything but an iPad will throw an exception. - Explicitly calling
dismissPopoverAnimated:
on aUIPopoverController
will not sendpopoverControllerDidDismissPopover:
to its delegate. - The
presentingViewController
property ofUIViewController
allows a modally-presented view controller to communicate with the view controller that presented it. - When a modally-presented view controller uses the
UIModalPresentationFormSheet
style, the presenting view controller is not sentviewWillAppear:
orviewDidAppear:
. - The two relationships between view controllers are parent-child relationships and presenting-presenter relationships.
UINavigationController
,UITabBarController
, andUISplitViewController
are all view controller containers, where each has aviewControllers
property.- A view controller container subclasses
UIViewController
and selectively adds the views ofviewControllers
as subviews of its own view. - The
parentViewController
property ofUIViewController
refers to the closest view controller ancestor in a family, or tree of view controller containers. - With a modally-presented view controller,
presentingViewController
andpresentedViewController
are valid for each view controller in each family, and always refer to the oldest ancestor in the other family.
- An
NSCoder
organizes the stream of data that it writes to the filesystem as a collection of key-value pairs. - Holding down the Option key and clicking on a class name presents a pop-up window with a brief description and links to its header file and its reference.
- Although a XIB file is not a standard archive, archiving is how Interface Builder writes and reads XIB files.
- In the application sandbox, directories
Documents/
andLibrary/Caches
contain data that persists between runs, but only the former is synchronized with iTunes. - Static method
archiveRootObject:toFile:
ofNSKeyedArchiver
archives an object implementingNSCoding
to the given filename. - When an overlay to handle an SMS message, push notification, phone call, or alarm appears on top of your application, it is in the inactive state.
- An application spends about ten seconds in the background state before it enters the suspended state.
- The inactive state loses the ability to receive events, the background state loses visibility, and the suspended state loses the ability to execute code.
- The operating system terminates suspended applications as needed when available memory is low; such an application receives no notification of this.
- Transitioning to the background state is a good place to save outstanding changes, because it's the last time it can execute code before entering the suspended state.
- Calling
writeToFile:atomically:
ofNSData
withYES
writes the data to a temporary file, and then renames that file to the first parameter. - In addition to
self
, the implicit variable_cmd
is the selector for the current method, and can be translated to a string usingNSStringFromSelector
. - The
localizedDescription
method ofNSError
returns a human-readable description that is suitable for display to the user. - Use
NSException
if the error lies with the programmer, andNSError
if a request is reasonable but could not be fulfilled. - To use
writeToFile:
andinitWithContentsOfFile:
with collection objects, they must contain only property list serializable objects, namelyNSString
,NSNumber
,NSDate
,NSData
,NSArray
, andNSDictionary
. - Files within the application bundle are read-only, and you cannot dynamically add files to the application bundle at runtime.
- To subclass
UITableViewCell
, add subviews to its content view, which is resized when the user enters editing mode, for example. - Function
UIGraphicsBeginImageContextWithOptions
creates a newCGContextRef
that is offscreen, and sets it as the current context. - Get a
UIImage
from the current context by callingUIGraphicsGetImageFromCurrentImageContext
, and thenUIGraphicsEndImageContext
to clean up. - To allow tapping an image to show a full-size image, add a transparent
UIControl
orUIButton
on top of the thumbnail. - When such a button is tapped, it invokes a method of the
UITableViewCell
subclass. This should invoke a block assigned by the controller to implement behavior. - Blocks are created on the stack and not the heap, and so the assignment of a block to a
UIView
or persisted instance must use thecopy
attribute. - Blocks own the objects that they capture from their enclosing scope, which can easily create a strong reference cycle.
- A block should instead capture a weak reference to whatever object owns it. When the block starts executing, assign that to a strong reference to ensure that exists while the block executes.
- A
UICollectionViewLayout
subclass controls the attributes of each cell, including its position and size, in aUICollectionView
. - A
UICollectionViewCell
has a content view with no subviews, and so you must subclass it if you are using aUICollectionView
.
- When a font is requested for a given text style, the system will use the preferred text size to return the appropriately configured font for that style.
- To react to users' changes in text size, you must subscribe to
UIContentSizeCategoryDidChangeNotification
and reassign the preferred fonts. - For a view to grow larger than its
intrinsicContentSize
in a given direction, there must be a constraint with a higher priority than that view's Content Hugging Priority. - For a view to grow smaller than its
intrinsicContentSize
in a given dimension, there must be a constraint with a higher priority than that view's Compression Resistance Priority. - Given the
preferredContentSize
property value ofUIApplication
, assign theheight
property of aUITableView
the correct row height. - The
awakeFromNib
method is called after unarchiving, and is a great place to do any additional UI work that cannot be done within the XIB file. - Modifying the
frame
orbounds
of a view will only persist until the next time the view is laid out based on the constraints that it has. - Constraints are instances of
NSLayoutConstraint
, so just like you can create outlets to views, you can create outlets to constraints. - A placeholder constraint in Interface Builder is only temporary and is removed at build time.
- Use placeholder constraints if adding a programmatic constraint creates a conflict, but removing the constraint in IB would warn about misplaced views or ambiguous layout.
NSURLRequest
holds all data necessary to communicate with a server, including anNSURL
instance, a caching policy, a timeout value, and any additional HTTP data.NSURLSessionTask
encapsulates the lifetime of a singleNSURLRequest
, and has methods to cancel, suspend, and resume the request.NSURLSession
acts as a configurable factory forNSURLSessionTask
instances.- To percent encode and decode a string, use methods
stringByAddingPercentEscapesUsingEncoding:
andstringByRemovingPercentEncoding
. - A
NSURLSessionTask
instance is always created in the suspended state, and so callingresume
on the task will start the request. - The main thread is also referred to as the UI thread, as any code that modifies the UI has to run on the main thread.
- By default,
NSURLSessionDataTask
runs the completion handler on a background thread, but you can transfer control to the main thread by callingdispatch_async
withdispatch_get_main_queue()
. - To respond to an authentication challenge, an
NSURLSessionDataDelegate
can return aNSURLCredential
containing a username and password. NSURLRequest
will compute the size in bytes of its body, and automatically add aContent-Length
header with this size.
- A
UISplitViewController
refers to an array of view controllers, but that array can only contain two view controllers. - The
splitViewController
message ofUIViewController
returns theUISplitViewController
it is a part of, even if it is not a member of the array ofUISplitViewController
. - By supplying a
UIBarButtonItem
to the delegate ofUISplitViewController
, tapping this button displays the master view controller in a specializedUIPopoverController
. - If the detail view controller does not specify a title for the
UIBarButtonItem
, then it won't appear, unless the master view controller specifies a title for itsnavigationItem
. - This requires placing the detail view controller inside a
UINavigationController
, unless you instantiate your ownUINavigationBar
orUIToolbar
to hold theUIBarButtonitem
.
- In Core Data, a table/class is called an entity, and its columns/properties are called its attributes.
- With a transformable attribute, a supplied
NSValueTransformer
subclass converts between instances of a class andNSData
for storage in Core Data. - An entity in a to-one relationship has a pointer to the related entity, while an entity with a to-many relationship has an
NSSet
containing all related entities. - An
NSManagedObject
works a bit like a dictionary, holding a key-value pair for every property in the entity. - If your model objects must do something in addition to holding data, subclass
NSManagedObject
, and associate that subclass with the entity in your model file. - Adding a
NSManagedObject
to the database invokes itsawakeFromInsert
method, which can contain the logic that is normally found in an initializer. - An
NSPersistentStoreCoordinator
uses your model file in the form of anNSManagedObjectModel
to interact with a SQLite database. - Calling
save:
on anNSManagedObjectContext
will update all records in the SQLite database with any changes since the last time it was saved. - You use an
NSPredicate
to select which instances anNSFetchRequest
should return, but you can also use it withfilteredArrayUsingPredicate:
ofNSArray
. - To persist a reorderable list to Core Data, add an
orderingValue
of typedouble
to each entity. When inserting an element, assign itsorderingValue
to the mean of that of its neighbors.