Today, I saw an article in the garden titled "Objective-C 2.0 with Cocoa Foundation --- 5, Class type, Selector and function pointer, you can't help but add comments to the code so that you can view it later. My personal experience: the "Class type variable" in obj-C is more flexible than the Object base Class in c #. It can be used to generate any type of instance (but it is not
NSObject ). If the selector SEL and function pointer IMP need to be related to c #, the two should be combined, which is similar to reflection + delegate in c #. A method name can be used.
String to directly call the method. Cattle. h
#import <Foundation/Foundation.h>@interface Cattle : NSObject {int legsCount;}- (void)saySomething;- (void)setLegsCount:(int) count;@end
Cattle. m
#import "Cattle.h"@implementation Cattle-(void) saySomething{NSLog(@"Hello, I am a cattle, I have %d legs.", legsCount);}-(void) setLegsCount:(int) count{legsCount = count;}@end
Subclass "Bull" Bull. h
#import <Foundation/Foundation.h>#import "Cattle.h"@interface Bull : Cattle {NSString *skinColor;}- (void)saySomething;- (NSString*) getSkinColor;- (void) setSkinColor:(NSString *) color;@end
Bull. m
#import "Bull.h"@implementation Bull-(void) saySomething{NSLog(@"Hello, I am a %@ bull, I have %d legs.", [self getSkinColor],legsCount);}-(NSString*) getSkinColor{return skinColor;}- (void) setSkinColor:(NSString *) color{skinColor = color;}@end
Proxy class DoProxy. h (the key code is here)
# Import <Foundation/Foundation. h> // define several string constants # defineSET_SKIN_COLOR @ "setSkinColor:" # defineBULL_CLASS @ "Bull" # defineCATTLE_CLASS @ "Cattle" @ interface DoProxy: NSObject {BOOL notFirstRun; id cattle [3]; // defines two selector SEL say; SEL skin; // defines a function pointer (the processing method of the traditional C Language) void (* setSkinColor_Func) (id, SEL, NSString *); // defines an IMP function pointer (recommended in obj-C) IMP say_Func; // defines a Class bullClass;}-(void) doWithCattleId :( id) aCattle colorParam :( NSString *) color;-(void) setAllIVars;-(void) SELFuncs;-(void) functionPointers; @ end
DoProxy. m
# Import "DoProxy. h "# import" Cattle. h "# import" Bull. h "@ implementation DoProxy // Initialize all variables-(void) setAllIVars {cattle [0] = [Cattle new]; bullClass = NSClassFromString (BULL_CLASS ); // that is, cattle [1] and cattle [2] are Bull class instances. cattle [1] = [bullClass new]; cattle [2] = [bullClass new]; say = @ selector (saySomething); skin = NSSelectorFromString (SET_SKIN_COLOR);} // initialization id-(void) doWithCattleId :( id) aCattle colorParam :( NSString *) Color {// if (notFirstRun = NO) {NSString * myName = NSStringFromSelector (_ cmd) during the first run ); // obtain the name NSLog (@ "Running in the method of % @", myName); notFirstRun = YES; // modify the initial run flag} NSString * cattleParamClassName = [aCattle className]; // obtain aCattle's "Class Name" // if aCattle is a Bull or Cattle class instance if ([cattleParamClassName isw.tostring: BULL_CLASS] | [cattleParamClassName isw.tostring: CATTLE_CLASS]) {[aCattle setLegs Count: 4]; // set the four legs of a cow if ([aCattle respondsToSelector: skin]) // if aCattle corresponds to a class, there is a defined method "setSkinColor" {[aCattle javasmselector: skin withObject: color]; // call the setSkinColor method} else {NSLog (@ "Hi, I am a % @, have not setSkinColor! ", CattleParamClassName); // otherwise, the corresponding prompt message is output.} [aCattle implements mselector: say]; // The saySomething method is last executed. (both methods are available in the Bull and Cattle classes, so it will certainly run)} else // If aCattle is neither a Bull class nor a Cattle class instance {NSString * yourClassName = [aCattle className]; NSLog (@ "Hi, you are a % @, but I like cattle or bull! ", YourClassName); // display information about this" "} // initialize the selector and the corresponding function-(void) SELFuncs {[self doWithCattleId: cattle [0] colorParam: @ "brown"]; [self doWithCattleId: cattle [1] colorParam: @ "red"]; [self doWithCattleId: cattle [2] colorParam: @ "black"]; [self doWithCattleId: self colorParam: @ "haha"]; // a heterogeneous self (that is, DoProxy itself) is intentionally input here ), doProxy is certainly not Bull or Cattle} // function pointer test-(void) functionPointers {// The first way to get the function pointer setSkinColor_Func = (void (*) (id, SE L, NSString *) [cattle [1] methodForSelector: skin]; // The preceding statement is actually equivalent to the following method: // IMP setSkinColor_Func = [cattle [1] methodForSelector: skin]; // use the second method to obtain the saySomething function pointer say_Func = [cattle [1] methodForSelector: say]; // call setSkinColorsetSkinColor_Func (cattle [1], skin, @ "verbose"); NSLog (@ "Running as a function pointer will be more efficiency! "); // Call the saySomething method say_Func (cattle [1], say);} @ end
Test the main function main ()
#import <Foundation/Foundation.h>#import "DoProxy.h"int main (int argc, const char * argv[]) {NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];DoProxy *doProxy = [DoProxy new];[doProxy setAllIVars];[doProxy SELFuncs];[doProxy functionPointers];[doProxy release];[pool drain];return 0;}
Running result:
21:40:33. 240 HelloSelector [630: a0f] Running in the method of doWithCattleId: colorParam:
21:40:33. 245 HelloSelector [630: a0f] Hi, I am a Cattle, have not setSkinColor!
21:40:33. 247 HelloSelector [630: a0f] Hello, I am a cattle, I have 4 legs.
21:40:33. 248 HelloSelector [630: a0f] Hello, I am a red bull, I have 4 legs.
21:40:33. 250 HelloSelector [630: a0f] Hello, I am a black bull, I have 4 legs.
21:40:33. 251 HelloSelector [630: a0f] Hi, you are a DoProxy, but I like cattle or bull!
21:40:33. 252 HelloSelector [630: a0f] Running as a function pointer will be more efficiency!
21:40:33. 254 HelloSelector [630: a0f] Hello, I am a verbose bull, I have 4 legs.
Author: Yang Guo under the bodhi tree
Source: http://www.cnblogs.com/yjmyzz/archive/2011/02/28/1967451.html
The copyright of this article is shared by the author and the blog Park. You are welcome to repost this article. However, you must retain this statement without the author's consent and provide a clear link to the original article on the article page. Otherwise, you will be held legally liable.