面试题
super相关
#import "MJPerson.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJStudent : MJPerson
@end
#import "MJStudent.h"
@implementation MJStudent
- (instancetype)init
{
if (self = [super init])
{
NSLog(@"%@", [self class]);
NSLog(@"%@", [self superclass]);
NSLog(@"%@", [super class]);
NSLog(@"%@", [super superclass]);
}
return self;
}
@end
上面这道面试题的结果是:
2022-05-16 14:05:52.283291+0800 RacTest[11763:1023402] MJStudent
2022-05-16 14:05:52.283407+0800 RacTest[11763:1023402] MJPerson
2022-05-16 14:05:52.283448+0800 RacTest[11763:1023402] MJStudent
2022-05-16 14:05:52.283487+0800 RacTest[11763:1023402] MJPerson
这是因为
-
[super message]
的底层实现消息接收者仍然是子类对象,接收class
消息的仍然是MJStudent
类,只是从父类开始查找方法的实现。 -
class
方法的实现在NSObject
里,不论是谁调用,方法实现是一样的。
isKindOfClass和isMemberOfClass区别
Person *person = [[Person alloc]init];
[person run];
NSLog(@"%d",[person isKindOfClass:[Person class]]);
NSLog(@"%d",[person isKindOfClass:[NSObject class]]);
NSLog(@"%d",[person isMemberOfClass:[Person class]]);
NSLog(@"%d",[person isMemberOfClass:[NSObject class]]);
上面代码的输出结果是:
2022-06-02 17:46:55.743553+0800 TestPod[31311:2266385] 1
2022-06-02 17:46:55.743642+0800 TestPod[31311:2266385] 1
2022-06-02 17:46:55.743755+0800 TestPod[31311:2266385] 1
2022-06-02 17:46:55.743856+0800 TestPod[31311:2266385] 0
即使用 isKindOfClass
时,实例对象只要是类的子类或者当前类的对象即可,而 isMemberOfClass
必须要是当前类的对象,如果是判断类是否是某一种元类则用下面方法:object_getClass([Person class])
NSLog(@"%d",[Person isMemberOfClass:object_getClass([Person class])]);
NSLog(@"%d",[Person isMemberOfClass:object_getClass([Person class])]);
NSLog(@"%d",[[Person class] isMemberOfClass:object_getClass([Person class])]);
NSLog(@"%d",[[Person class] isMemberOfClass:object_getClass([Person class])]);
LLVM的中间代码
- Objective-C在变为机器代码之前,会被LLVM编译器转为中间代码(Intermediate Representation)
- 可以使用以下命令行指令生成中间代码,但是这种代码比较难懂,所以还是转为C++后看比较合适
- clang -emit-llvm -$ main.m
网友评论