Cocoa framework For iOS (2) object allocation initialization, introspection, and Singleton

Source: Internet
Author: User
Document directory
  • Initialization Problems
  • Implementation Initialization Method

Next, take the Cocoa framework summary For iOS (1) and continue to summarize the Cocoa objects.

1. We all know that there are two steps to create a Cocoa object: alloc and init (Object allocation and initialization. Initialization is usually followed by object allocation, but the two operations have different functions. Allocation object: Cocoa allocates a block of memory for the object from the virtual memory of the application. Cocoa calculates the memory size and allocates memory based on the instance variables of the object (the sort order of types and variables. To allocate memory, you need Class Object( Class ObjectThe previous article details the origins and functions of alloc and allocWithZone: send messages. The message returns an uninitialized class instance. In addition to memory allocation, other important tasks are also done for sending and allocating messages:
  • Set the number of objects to 1.
  • The isa pointer of the allocated object points to the class object.
  • Initialize all instance variables of the object to 0. It can also be understood as the equivalent type of 0: nil NULL
In this way, all objects have isa pointers and point to their corresponding class objects, so that the object can find its runtime information. For example, the location of an object on the hierarchy (which is the parent class, which is the subclass, and other information), the Protocol it implements, and the message it can respond. Even so, the object after alloc is not a usable object and must be initialized. 1.1 The initialization process of an object is to set the instance variable of the object to a valid and reasonable value, or the data you want. If your class does not implement the initialization method, it will call the parent class. Form of initialization methodThe initialization method is the instance method, and the returned object is the id type. The initialization method is formal and cannot be gibberish. You can have multiple parameters, but it must start with init, for example,-(id) initWithArray :( NSArray *) array; (from NSSet) parameter format: WithType: initialization problems? What's the problem !? Sometimes initialization does not return a new object. When? For example, we are familiar with the singleton mode. In addition, when an attribute of an object is unique. The id of the account class is unique. If an id is an existing id, the account object corresponding to the existing id is returned. At this time, we need:
  • Release the objects you just allocated (isn't it a waste of resources? It's useless to release the objects you just allocated? There's no way to do it)
  • Returns an existing account object.
Sometimes you fail to initialize the object and some operations are required. How can it fail? For example, initFromFile: This initialization method is used to initialize a file. If the file does not exist, initialization fails. What should I do if the initialization fails:
  • Release the allocated object
  • Return nil
The object cannot be initialized repeatedly. Otherwise, an NSInvalidArgumentException exception occurs. To implement the initialization method, you may need to write the initialization method for the custom class. You can have one or more initialization methods, depending on the needs of the class you designed. However, follow these steps to implement initialization:
  1. First, you must call the initialization method of the parent class.
  2. Check the objects returned by the parent class initialization. If nil is returned, the initialization fails and nil is returned.
  3. When initializing instance variables, if they are referenced by other objects, retain and copy are required.
  4. If an existing object is returned, release the newly assigned object (the class of the Account mentioned earlier)
  5. If the initialization fails (for example, the file fails to be initialized), nil is returned.
  6. If no problem exists, return self. Initialization complete
The following example shows the steps:
- (id)initWithAccountID:(NSString *)identifier {    if ( self = [super init] ) {        Account *ac = [accountDictionary objectForKey:identifier];        if (ac) { // object with that ID already exists            [self release];            return [ac retain];        }         if (identifier) {            accountID = [identifier copy]; // accountID is instance variable            [accountDictionary setObject:self forKey:identifier];            return self;        } else {            [self release];            return nil;        }    } else        return nil;}

Note: During subclass initialization, you must first call the initialization method of the parent class to ensure that the instance variables of the parent class in the inheritance chain are correctly assigned values.

 

Explain the initialization process of the inheritance chain:

1.2 The dealloc and init Methods Echo each other. Dealloc ensures that the instance variables of the object and the dynamically allocated memory are correctly released. Unlike the init method, the dealloc of the parent class is called after other classes are released.
- (void)dealloc {    [accountDictionary release];    if ( mallocdChunk != NULL )        free(mallocdChunk);    [super dealloc];}

1.3 factory method combines the allocation object and initialization into one, returns the created object, and automatically releases it. The form of these methods is generally: + (type) className... NSDate factory class method:

+ (id)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs;+ (id)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secs;+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)secs;

Test the first code:

 

    NSDate *now = [NSDate dateWithTimeIntervalSinceNow: 0];    NSLog(@"now:%@",now);

 

Printed now: 06:39:25 + 0000

Reference the current time as the benchmark, 0 is the current time, + 0000 represents the time zone, we are the 8 time zone, + 8 is. If the parameter is 24*60*60, it is the time of tomorrow, and if it is a negative number, it is the time of yesterday.

NSData provides the following factory methods:

+ (id)dataWithBytes:(const void *)bytes length:(unsigned)length;+ (id)dataWithBytesNoCopy:(void *)bytes length:(unsigned)length;+ (id)dataWithBytesNoCopy:(void *)bytes length:(unsigned)length        freeWhenDone:(BOOL)b;+ (id)dataWithContentsOfFile:(NSString *)path;+ (id)dataWithContentsOfURL:(NSURL *)url;+ (id)dataWithContentsOfMappedFile:(NSString *)path;
For example, + (id)

The example of dataWithContentsOfURL allows you to download images without any pressure.

        NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];        NSData * data = [NSData dataWithContentsOfURL:url];        UIImage *image = [[UIImage alloc]initWithData:data];
2. Introspection is an important feature of object-oriented languages and environments. Objective-C and Cocoa are doing well in this regard. Introspection is the ability of an object to check its own details as a runtime object. These details include the location of the object on the inheritance tree, whether the object complies with a specific protocol, and whether it can respond to a specific message. The NSObject protocol and class define many introspection methods for querying runtime information to identify objects based on their features.

Flexible Use of introspection capabilities can make your programs more stable and powerful. Introspection can avoid errors in message distribution and incorrect judgment of equal objects. The following describes some practical methods for introspection:

2.1 The NSObject protocol for locating the inheritance relationship declares several methods to determine the position of an object in the class hierarchy. Class returns the Class Object of the class. Superclass returns the Class Object of the parent Class. Take the following example:
while ( id anObject = [objectEnumerator nextObject] ) {    if ( [self class] == [anObject superclass] ) {        // do something appropriate...    }}

The two Class objects returned are equal.
Check the subordination of class objects: isKindOfClass: determines whether it is an instance of this class or a subclass of this class. IsMemberOfClass: This is more strict and determines whether it is an instance of this class. Example:

if ([item isKindOfClass:[NSData class]]) {    const unsigned char *bytes = [item bytes];    unsigned int length = [item length];    // ...}
2.2 determine whether the method is implemented or whether the NSObject protocol is followed. There are two more powerful introspection methods, respondsToSelector: And conformsToProtocol :. The two are instance methods. RespondsToSelector determines whether the object implements a certain method, and conformsToProtocol determines whether it complies with the specified formal protocol (it means all the methods to implement the Protocol ). All classes that inherit NSObject have these two methods. RespondsToSelector example:
- (void)doCommandBySelector:(SEL)aSelector {    if ([self respondsToSelector:aSelector]) {        [self performSelector:aSelector withObject:nil];    } else {        [_client doCommandBySelector:aSelector];    }}

 

2.3 comparison of Objects

Hash and isEqual: methods are both declared in the NSObject protocol and closely related to each other. The implementation of the hash method will return an integer number. Two objects are equal, which means they have the same hash value. If your object may be contained in a collection like NSSet, You need to define the hash method and ensure that the method returns the same hash value when the two objects are equal. However, the default isEqual implementation in the NSObject class simply checks whether the pointer is equal.

Example of the isEqual method:

- (void)saveDefaults {    NSDictionary *prefs = [self preferences];    if (![origValues isEqual:prefs])         [Preferences savePreferencesToDefaults:prefs];}

If an instance variable is added to the subclass, you must compare the instance variables of the subclass to determine whether the objects are equal. You must reload the isEqual method:

- (BOOL)isEqual:(id)other {    if (other == self)         return YES;    if (!other || ![other isKindOfClass:[self class]])         return NO;    return [self isEqualToWidget:other];} - (BOOL)isEqualToWidget:(MyWidget *)aWidget {    if (self == aWidget)         return YES;    if (![(id)[self name] isEqual:[aWidget name]])        return NO;    if (![[self data] isEqualToData:[aWidget data]])        return NO;    return YES;}
3. mutable 3.1 why do I need to select a mutable object or an immutable object when creating an object? How can we decide. Let's take a look at the reasons for the existence of mutable and immutable objects. The variable object class has the Mutable keyword before it. These classes include:
  • NSMutableArray
  • NSMutableDictionary
  • NSMutableSet
  • NSMutableIndexSet
  • NSMutableCharacterSet
  • NSMutableData
  • NSMutableString
  • NSMutableAttributedString
  • NSMutableURLRequest
They are all subclasses of the corresponding immutable class. If the object is variable, it is insecure and unreliable in some scenarios. For example, if your object is passed to a method as a parameter, you do not want your object to be changed. In this case, your variable is changed. This is the result you don't want. In other scenarios, the opposite is true. OK. In order to correspond to different scenarios, the object must be variable or immutable. 3.2 when to use a mutable object when you need to frequently or constantly modify the content of an object after it is created, use a mutable object
Sometimes it may be better to replace another with an immutable object. For example, most instance variables with reserved strings should be assigned to an immutable NSString object, which is replaced by the "setter" method.
The variability prompt is based on the return type.
If you cannot determine whether an object is variable, treat it as immutable.
4. To create a single instance, follow these steps:
  • Declare a static instance of a singleton object and initialize it to nil.
  • An instance of this class is generated in the class factory method (name is similar to "sharedInstance" or "sharedManager") of this class, but only when the static instance is nil.
  • Reload allocWithZone: method to ensure that no other object is allocated when you try to allocate or Initialize an instance of the class directly (instead of through the class factory method.
  • Basic protocol implementation methods: copyWithZone:, release, retain, retainCount, and autorelease to ensure the status of the Singleton.
Code example for implementing singleton:
static MyGizmoClass *sharedGizmoManager = nil; + (MyGizmoClass*)sharedManager{    @synchronized(self) {        if (sharedGizmoManager == nil) {            [[self alloc] init]; // assignment not done here        }    }    return sharedGizmoManager;} + (id)allocWithZone:(NSZone *)zone{    @synchronized(self) {        if (sharedGizmoManager == nil) {            sharedGizmoManager = [super allocWithZone:zone];            return sharedGizmoManager;  // assignment and return on first allocation        }    }    return nil; //on subsequent allocation attempts return nil} - (id)copyWithZone:(NSZone *)zone{    return self;} - (id)retain{    return self;} - (unsigned)retainCount{    return UINT_MAX;  //denotes an object that cannot be released} - (void)release{    //do nothing} - (id)autorelease{    return self;}

Refer:

Http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW59

Rong Fangzhi (http://blog.csdn.net/totogo2010)

This article follows the "signature-non-commercial use-consistency" creation public agreement

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.