iOS面接集錦
5827 ワード
1.OC言語のメリットとデメリット
メリット: category
posing
動特性runtime:関数はIMP動的バインディングを実現し、resolve 指標計算 フレックスメッセージ伝達 は複雑すぎるC派生言語ではありません Objective_CとC++は混成することができる;欠点: は、メタネーミングスペース をサポートしていません.
演算子リロード はサポートされていません.
多重継承 はサポートされていない.
動的ランタイムタイプを使用し、すべての方法は関数呼び出しであり、多くのコンパイル時最適化スキームは、インライン関数などの使用できず、パフォーマンスが劣っています.
2.OCメッセージ送信メカニズム
3.OCメッセージ転送メカニズム
4.OCシミュレーション多重継承
//SubClass.h
//SubClass.m
//テスト
メリット:
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"];