An object’s life cycle—that is, its runtime life from its creation to its destruction—is marked or determined by various messages it receives. An object comes into being when a program explicitly allocates and initializes it or when it makes a copy of another object. An object can also begin its runtime life during unarchiving, when it is asked to decode itself from the archive byte stream. If an object was unarchived from a nib file, it receives an awakeFromNib message after all objects in the nib file have been loaded into memory
After the creation and initialization phase, an object remains in memory as long as its retain count is greater than zero. Other objects in the program may express an ownership interest in an object by sending it retain or by copying it, and then later relinquish that ownership interest by sending release to the object. While the object is viable, a program may begin the archiving process, in which the object encodes its state in the archive byte stream. When the object receives its final release message, its retain count drops to zero. Consequently, the object’s dealloc method is called, which frees any objects or other memory it has allocated, and the object is destroyed.
Object creation
An object comes into runtime existence through a two-step process that allocates memory for the object and sets its state to reasonable initial values. To allocate an Objective-C object, send an alloc or allocWithZone: message to the object’s class. The runtime allocates memory for the object and returns a “raw” (uninitialized) instance of the class. It also sets a pointer (known as the isa pointer) to the object’s class, zeros out all instance variables to appropriately typed values, and sets the object’s retain count to 1.
After you allocate an object, you must initialize it. Initialization sets the instance variables of an object to reasonable initial values. It can also allocate and prepare other global resources needed by the object. You initialize an object by invoking an init method or some other method whose name begins with init.. If these methods succeed in initializing an object, they return it; otherwise, they return nil. If an object’s class does not implement an initializer, the Objective-C runtime invokes the initializer of the nearest ancestor instead.
Memory-Management Implications
In code that explicitly manages memory, the allocation and initialization procedure returns an object with a retain count of 1. This means that the client receiving the object now “owns” the object and is responsible for releasing it. You release it by sending it a release or autorelease message; the latter message causes a delayed release. If you do not release objects that you own, your program will leak memory.
Factory Methods
A factory method is a class method that, as a convenience to clients, creates an instance of a class. A factory method combines allocation and initialization in one step and returns an autoreleased instance of the class. Because the received object is autoreleased, the client must copy or retain the instance if it wants it to persist in memory. The names of factory methods have the following initial form:
+ (id)typeRemainderOfMethodName
Object archiving
Archiving is the process of converting a group of related objects to a form that can be stored or transferred between applications. The end result of archiving—an archive—is a stream of bytes that records the identity of objects, their encapsulated values, and their relationships with other objects. Unarchiving, the reverse process, takes an archive and reconstitutes an identical network of objects.
For its instances to be included in an archive, a class must adopt the NSCoding protocol and implement the required methods for encoding and decoding objects. Cocoa archives can hold Objective-C objects, scalar values, C arrays, structures, and strings. Archives store the types of objects along with the encapsulated data, so an object decoded from a stream of bytes is of the same class as the object that was originally encoded into the stream.
1. Keyed and Sequential Archivers :
The Foundation framework provides two sets of classes for archiving and unarchiving networks of objects. They include methods for initiating the archiving and unarchiving processes and for encoding and decoding the instance data of your objects. Objects of these classes are sometimes referred to as archivers and unarchivers.
Keyed archivers and unarchivers (NSKeyedArchiver and NSKeyedUnarchiver). These objects use string keys as identifiers of the data to be encoded and decoded. They are the preferred objects for archiving and unarchiving objects, especially with new applications.
Sequential archivers and unarchivers (NSArchiver and NSUnarchiver). This “old-style” archiver encodes object state in a certain order; the unarchiver expects to decode object state in the same order. Their intended use is for legacy code; new applications should use keyed archives instead.
2. Creating and Decoding Keyed Archives
An application creates an archive by invoking the archiveRootObject:toFile: class method of NSKeyedArchiver. The first parameter of this method takes a reference to the root object of an object graph. Starting with this root object, each object in the graph that conforms to the NSCoding protocol is given an opportunity to encode itself into the archive. The resulting byte stream is written to the specified file.
Decoding an archive proceeds in the opposite direction. An application calls the NSKeyedUnarchiver class method unarchiveObjectWithFile:. Given an archive file, the method recreates the object graph, asking the class of each object in the graph to decode the relevant data in the byte stream and recreate the object. The method ends by returning a reference to the root object.
Memory management is the programming discipline of managing the life cycles of objects and freeing them when they are no longer needed. Managing object memory is a matter of performance; if an application doesn’t free unneeded objects, its memory footprint grows and performance suffers. Memory management in a Cocoa application that doesn’t use garbage collection is based on a reference counting model. When you create or copy an object, its retain count is 1. Thereafter other objects may express an ownership interest in your object, which increments its retain count. The owners of an object may also relinquish their ownership interest in it, which decrements the retain count. When the retain count becomes zero, the object is deallocated (destroyed).
Memory-Management Rules
Memory-management rules, sometimes referred to as the ownership policy, help you to explicitly manage memory in Objective-C code.
You own any object you create by allocating memory for it or copying it.
Conversely, if you are not the creator of an object and have not expressed an ownership interest, you must not release it.
If you receive an object from elsewhere in your program, it is normally guaranteed to remain valid within the method or function it was received in. If you want it to remain valid beyond that scope, you should retain or copy it. If you try to release an object that has already been deallocated, your program crashes.
Aspects of Memory Management
The following concepts are essential to understanding and properly managing object memory:
Autorelease pools. Sending autorelease to an object marks the object for later release, which is useful when you want the released object to persist beyond the current scope. Autoreleasing an object puts it in an autorelease pool (an instance of NSAutoreleasePool), which is created for an arbitrary program scope. When program execution exits that scope, the objects in the pool are released.
Deallocation. When an object’s retain count drops to zero, the runtime calls the dealloc method of the object’s class just before it destroys the object. A class implements this method to free any resources the object holds, including objects pointed to by its instance variables.
Factory methods. Many framework classes define class methods that, as a convenience, create objects of the class for you. These returned objects are not guaranteed to be valid beyond the receiving method’s scope.
Object encoding
Object encoding converts an object’s class identity and state to a format that can be stored or transferred between processes. The class type and instance data are written to a byte stream that can persist after a program terminates. When the program is launched again, a newly allocated object can decode the stored representation of itself and restore itself to its previous runtime state. Encoding usually occurs in concert with archiving, which puts a graph of objects into a format (an archive) that can be written to the file system; unarchiving operates on an archive, asking each object in the stored graph to decode itself.
Object encoding is also used in the OS X distributed objects API for transferring objects from one process to another. However, its most common use is for archiving, which like a property list, is a mechanism for object persistence.
How to Encode and Decode Objects
For your subclass to encode and decode its instances, it must conform to the NSCoding protocol and implement two methods: initWithCoder: and encodeWithCoder:. When a program unarchives or archives an object graph, these methods are invoked. In the encodeWithCoder: method, you encode the values of an object’s important instance variables; in the initWithCoder: method, you decode those values and reassign them to their instance variables. If an object receives an initWithCoder: message, none of its initializer methods are invoked.
The sole argument of initWithCoder: and encodeWithCoder: is an NSCoder object whose purpose is to perform the actual decoding or encoding. Because NSCoder is an abstract class, the coder object is in most cases an instance of one of the following concrete subclasses: NSKeyedArchiver, NSKeyedUnarchiver, NSArchiver, NSUnarchiver. The archiver classes declare methods for encoding an object’s instance variables; the unarchiver classes declare methods for decoding instance variables.
The NSCoder methods work on objects, scalars, C arrays, structures, and strings, and on pointers to these types. Before you encode or decode an instance variable of your own class, be sure to first invoke the superclass implementation of initWithCoder: or encodeWithCoder:. When you decode objects from the byte stream, be sure to retain or copy them when you assign them to their instance variables.
Keyed Versus Sequential Archiving
Two of the concrete NSCoder subclasses are different from each other in a fundamental way. The “keyed” archiver class (NSKeyedArchiver and NSKeyedUnarchiver) associate an encoded value with a string key and use that same key when decoding that value; thus instance variables can be encoded and decoded in any sequence. With the other type of coder (NSArchiver and NSUnarchiver) you encode instance variables in a certain sequence, and you must decode them in the same sequence. The sequential coders should be used only with legacy code; new subclasses should use keyed archive coders.
I am pretty sure that even a few experienced iOS developers would have a hard time defining the iOS SDK in one sentence. The acronym SDK stands for Software Development Kit . The iOS SDK contains the tools and resources to develop native iOS applications, which means that the SDK enables developers to develop, install, run, and test applications in the simulator and on physical devices. The two driving forces powering native iOS applications are Swift (or Objective-C) and the native iOS system frameworks. In the previous articles, we explored the Swift programming language. In this article, I want to explore the frameworks that power native iOS applications. You now know what the iOS SDK is, but what makes an application qualify as a native iOS application? The simple answer is that an iOS application is an application that runs on an iOS device. That's only half the truth, though. What about web applications that run in Safari? An iOS application is...
I can’t believe it is over six years since I first wrote about local notifications in iOS 4 . Well in iOS 10 Apple has deprecated UILocalNotification which means it is time to get familiar with a new notifications framework. Setup This is a long post so let’s start easy by importing the new notifications framework: // Swift import UserNotifications // Objective-C (with modules enabled) @ import UserNotifications; You manage notifications through a shared UNUserNotificationCenter object: // Swift let center = UNUserNotificationCenter .current() // Objective-C UNUserNotificationCenter *center = [ UNUserNotificationCenter currentNotificationCenter]; Authorization As with the older notifications framework you need to have the user’s permission for the types of notification your App will use. Make the request early in your App life cycle such as in application:didFinishLaunchingWithOptions: . The first time your App requests auth...
Performance Tips for IOS Application At each step in the development of your app, consider the implications of your design choices on the overall performance of your app. Power usage and memory consumption are extremely important considerations for iOS apps, and there are many other considerations as well. The following sections describe the factors you should consider throughout the development process. 1. Reduce Your App’s Power Consumption Power consumption on mobile devices is always an issue. The power management system in iOS conserves power by shutting down any hardware features that are not currently being used. You can help improve battery life by optimizing your use of the following features: The CPU Wi-Fi, Bluetooth, and baseband (EDGE, 3G) radios The Core Location framework The accelerometers The disk The goal of your optimizations should be to do the most work you can in the most efficient way possible. You should always optimize your app’...
Awesome Post!! IOS Developer, go through once!!
ReplyDeletethanks for these
ReplyDeleteinformation