iOS面接集錦

5827 ワード

1.OC言語のメリットとデメリット
メリット:
  • category

  • posing

  • 動特性runtime:関数はIMP動的バインディングを実現し、resolve
  • 指標計算
  • フレックスメッセージ伝達
  • は複雑すぎるC派生言語ではありません
  • Objective_CとC++は混成することができる;欠点:
  • は、メタネーミングスペース
  • をサポートしていません.
  • 演算子リロード
  • はサポートされていません.
  • 多重継承
  • はサポートされていない.
  • 動的ランタイムタイプを使用し、すべての方法は関数呼び出しであり、多くのコンパイル時最適化スキームは、インライン関数などの使用できず、パフォーマンスが劣っています.


  • 2.OCメッセージ送信メカニズム
        // 1.    
        ViewController *VC = [ViewController new];
        [VC testCommand];
        
        // 2.   objc_msgSend     
        ViewController *VC1 = ((ViewController *(*)(id, SEL))objc_msgSend)([ViewController class], @selector(alloc));
        VC1 = ((ViewController *(*)(id, SEL))objc_msgSend)(VC1, @selector(init));
        ((ViewController *(*)(id, SEL))objc_msgSend)(VC1, @selector(testCommand));
        
        // 3.    performSelector map   
        [VC performSelector:@selector(testCommand) withObject:@"132"];
    

    3.OCメッセージ転送メカニズム
    @interface ADDIMP :NSObject
    - (void)testCommand1;
    @end
    
    @implementation ADDIMP
    - (void)testCommand1 {
        NSLog(@"%s
    IMP ", __FUNCTION__); } @end @interface ViewController () // , - (void)testCommand1; @end @implementation ViewController // IMP void dynamicMethodIMP(id self, SEL _cmd) { printf("%s", __func__); } // 1. , runtime IMP + (BOOL)resolveInstanceMethod:(SEL)sel { NSLog(@"sel =%@", NSStringFromSelector(sel)); // if (sel == NSSelectorFromString(@"testCommand1")) { // NSLog(@"%s
    IMP ", __FUNCTION__); // class_addMethod(self, sel, (IMP)dynamicMethodIMP, "v@:"); // return YES; // } return [super resolveInstanceMethod:sel]; } // 2. - (id)forwardingTargetForSelector:(SEL)aSelector { NSLog(@"%s
    IMP ", __FUNCTION__); // if (aSelector == NSSelectorFromString(@"testCommand1")){ // // return [ADDIMP new]; // } return [super forwardingTargetForSelector:aSelector]; } // 3. // 3.1 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { if (aSelector == NSSelectorFromString(@"testCommand1")){ NSMethodSignature *sign = [NSMethodSignature signatureWithObjCTypes:"v@:"]; return sign; } return [super methodSignatureForSelector:aSelector]; } // 3.2 - (void)forwardInvocation:(NSInvocation *)anInvocation { SEL aSelector = [anInvocation selector]; ADDIMP *add = [ADDIMP new]; if ([add respondsToSelector:aSelector]) [anInvocation invokeWithTarget:add]; else [super forwardInvocation:anInvocation]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self testCommand1]; } @end

    4.OCシミュレーション多重継承
    //SubClass.h
    #import 
    
    @protocol ClassOne_protocol
    - (void)ClassOneString:(NSString *)string;
    @end
    
    @interface ClassOne : NSObject 
    
    @end
    
    @protocol ClassTwo_protocol
    - (void)ClassTwoString:(NSString *)string;
    @end
    @interface ClassTwo : NSObject
    
    @end
    
    @interface SubClass : NSProxy 
    + (instancetype)subClass;
    @end
    
    

    //SubClass.m
    #import "SubClass.h"
    #import 
     
    @implementation ClassOne
    - (void)ClassOneString:(NSString *)string {
        NSLog(@"
    %s
    ClassOneString
    ", __FUNCTION__); } @end @implementation ClassTwo - (void)ClassTwoString:(NSString *)string { NSLog(@"
    %s
    ClassTwoString
    ", __FUNCTION__); } @end @implementation SubClass{ NSMutableDictionary *_methodMap; } + (instancetype)subClass { return [[SubClass alloc] init]; } - (instancetype)init { _methodMap = [NSMutableDictionary dictionary]; [self registerMethodsWithTarget:[ClassOne new]]; [self registerMethodsWithTarget:[ClassTwo new]]; return self; } - (void)registerMethodsWithTarget:(id)target { unsigned int count = 0; // Method *methodList = class_copyMethodList([target class], &count); // for (NSInteger i = 0; i < count; i++) { Method method = methodList[i]; SEL sel = method_getName(method); [_methodMap setObject:target forKey:NSStringFromSelector(sel)]; } // dealloc free(methodList); } // , - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { // 1. NSString *methodName = NSStringFromSelector(aSelector); // 2. id target = [_methodMap objectForKey:methodName]; // 3. if(target && [target respondsToSelector:aSelector]) { return [target methodSignatureForSelector:aSelector]; } return [super methodSignatureForSelector:aSelector]; } // - (void)forwardInvocation:(NSInvocation *)anInvocation { SEL sel = anInvocation.selector; NSString *methodName = NSStringFromSelector(sel); id target = [_methodMap objectForKey:methodName]; if (target && [target respondsToSelector:sel]) { // [anInvocation invokeWithTarget:target]; }else [super forwardInvocation:anInvocation]; } @end

    //テスト
       SubClass *subClass = [SubClass subClass]; 
       [subClass ClassOneString:@"111111111"];
       [subClass ClassTwoString:@"222222222"];