In-depth analysis of iPhone introspection Mechanism

Source: Internet
Author: User

IPhone IntrospectionThe Mechanism is what we will introduce in this article. We will learn in detail from the evaluation of inheritance relationships, method implementation and protocol compliance, and object comparison.IPhone IntrospectionMechanism. Let's first look at the details.

IntrospectionIntrospection) is a powerful feature of the object-oriented language and environment.CocoaIt is particularly rich in this aspect. Introspection is the ability of an object to reveal its 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.

Wise Use of introspection can make Object-oriented Programs more efficient and robust. It helps avoid errors in message distribution, errors in assuming that objects are equal, and similar issues. The following section describes how to effectively use NSObject's introspection method in code.

Evaluate the inheritance relationship

Once you know what class an object belongs to, you may already know this object quite well. You can know what capabilities it has, what attributes it has, and what messages it can respond. Even if you cannot understand the class to which the object belongs after saving, you can also know that the object cannot respond to specific messages.

The NSObject Protocol declares several methods to determine the position of an object in the class hierarchy. These methods operate at different granularities. For example, the class and superclass instance methods return Class objects that represent classes and classes respectively. To use these methods, we need to compare one Class Object with another. List 2-7 provides an example of simple usage that may be of no value.

Use classes and superclasses

 
 
  1. // ...  
  2. while ( id anObject = [objectEnumerator nextObject] ) {  
  3.  if ( [self class] == [anObject superclass] ) {  
  4.  // do something appropriate...  
  5.  }  

Note: Sometimes you need to use the class or superclass method to obtain the correct class message receiver.

It is more common to check the subordination of the object class. In this case, you need to send an isKindOfClass: Or isMemberOfClass: Message to the object. The previous method returns whether the receiver is an instance of the given class or its inherited class. isMemberOfClass: the message tells you whether the receiver is an instance of the specified class. IsKindOfClass: A method is usually more useful because it can be used to determine whether a series of messages can be sent to the object. Consider the code snippets in the list from 2 to 8:

Use isKindOfClass: Method

 
 
  1. if ([item isKindOfClass:[NSData class]]) {  
  2.  const unsigned char *bytes = [item bytes];  
  3.  unsigned int length = [item length];  
  4.  // ...  

After confirming that the tem object is an instance of the NSData class's inheritance class, the code will know that the bytes and length messages of NSData can be sent to it. Assuming that item is an instance of the NSMutableData class, the difference between isKindOfClass: And isMemberOfClass: becomes more obvious. If you call isMemberOfClass: instead of isKindOfClass:, the code in the condition control block will never be executed, Because item is not an NSData class instance, but an instance of its subclass NSMutableData.

Method implementation and Protocol Compliance

NSObject also has two more powerful introspection Methods: respondsToSelector: And conformsToProtocol :. The two methods tell you whether an object implements a specific method and whether it complies with the specified formal protocol, that is, whether the object adopts the protocol and implements all the methods of the Protocol ).

In code, you can use these methods in a similar case. By using these methods, you can determine whether a message or message set can respond correctly before sending it to some potential anonymous objects. Check Before sending a message to avoid running exceptions caused by unrecognized selector.

In the implementation of informal protocols, this protocol is the basis of the delegate technology), Application Kit is to check whether the delegate object implements this method through respondsToSelector: method before calling the delegate method ).

Shows how to use the respondsToSelector: Method in code.

Use respondsToSelector: Method

 
 
  1. - (void)doCommandBySelector:(SEL)aSelector {  
  2.  if ([self respondsToSelector:aSelector]) {  
  3.  [self performSelector:aSelector withObject:nil];  
  4.  } else {  
  5.  [_client doCommandBySelector:aSelector];  
  6.  }  

Shows how to use conformsToProtocol in code: method:

Use conformsToProtocol: Method

 
 
  1. // ...  
  2. if (!([((id)testObject) conformsToProtocol:@protocol(NSMenuItem)])) {  
  3.  NSLog(@"Custom MenuItem, '%@', not loaded; it must conform to the  
  4.  'NSMenuItem' protocol.\n", [testObject class]);  
  5.  [testObject release];  
  6.  testObject = nil;  

Object comparison

Hash and isEqual: although the method is not strictIntrospectionMethod, but can play a similar role, is an indispensable runtime tool for object identification and comparison. They do not query object information from the running environment, but rely on the comparison logic of specific classes.

Hash and isEqual: methods are both declared in the NSObject protocol and closely related to each other. The hash method must return an integer as the table address in the hash table structure. Two objects are equal to isEqual: the judgment result of the method), 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. Default isEqual in NSObject class: The Implementation simply checks whether the pointer is equal.

IsEqual: Is used directly. It compares the receiver of a message with the object passed in through parameters. Objects can often be compared at runtime to decide what to do to objects. As shown in Table 2-11, you can use isEqual: to determine whether to perform an action. In this example, an action is used to save the modified preset information.

Use isEqual: Method

 
 
  1. - (void)saveDefaults {  
  2.  NSDictionary *prefs = [self preferences];  
  3.  if (![origValues isEqual:prefs])  
  4.  [Preferences savePreferencesToDefaults:prefs];  

If you are creating a subclass, you may need to overload the isEqual: Method to further check whether the object is equal. Subclass may define additional attributes. When two instances are considered equal, the attribute values must be the same. For example, if you create a NSObject subclass named MyWidget, the class contains two instance variables: name and data. When two instances of MyWidget are considered equal, these variables must have the same value. List 2-12 shows how to implement isEqual in the MyWidget class: method.

Overload isEqual: Method

 
 
  1. - (BOOL)isEqual:(id)other {  
  2.  if (other == self)   
  3.  return YES;  
  4.  if (!other || ![other isKindOfClass:[self class]])  
  5.  return NO;  
  6.  return [self isEqualToWidget:other];  
  7. }  
  8.  
  9. - (BOOL)isEqualToWidget:(MyWidget *)aWidget {  
  10.  if (self == aWidget)  
  11.  return YES;  
  12.  if (![(id)[self name] isEqual:[aWidget name]])  
  13.  return NO;  
  14.  if (![[self data] isEqualToData:[aWidget data]])  
  15.  return NO;  
  16.  return YES;  

IsEqual: The method first checks the equality of the pointer, then the class equality, and finally calls the object comparator for comparison. The name of the comparator indicates the Class Name of the object involved in the comparison. This type of comparator performs a forced type check on the passed object. YesCocoaCommon conventions in: is1_tostring of NSString: And is1_totimezone of NSTimeZone: are two such examples. In this example, the comparator of a specific class is is‑towidget :), which is responsible for executing the equality of name and data variables.

InCocoa frameworkAll isEqualToType: nil is not a proper parameter in the method, and exceptions are thrown when the implementation of these methods receives the nil parameter. However, for backward compatibility,Cocoa frameworkIsEqual in: The method can receive nil values. In this case, NO is returned.

Summary: in-depth analysisIPhone IntrospectionI hope this article will help you with the introduction of the mechanism!

Related Article

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.