@interface TestObj :NSObject
@property(copy, nonatomic)NSString *name;
@end
@implementation TestObj
- (void)testName{
NSLog(@"name:%@",self.name);
}
@end
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
id tclass =[TestObj class];
void * vid = &tclass;
[(__bridge id)vid testName];
}
@end
日志:
name: <ViewController: 0x7ff3584b6580>
我的理解是vid
是指向TestObj
类对象地址的指针,那么为什么vid
可以直接发送到testName
实例方法?
另外,为什么testName
方法调用NSLog
会输出<ViewController: 0x7ff3584b6580>
而不是nil?
感谢。
答案 0 :(得分:1)
我认为你基本上很幸运,你没有使用该代码崩溃。
首先,类方法以+
而不是-
开头 - 这是您正在实现的实例方法。
@interface TestObj :NSObject
@property(copy, nonatomic)NSString *name;
@end
@implementation TestObj
+ (void)testName{
NSLog(@"name:%@", @"TestObj"); // cannot reference ivars or properties in class method
}
@end
...
Class classObject = [TestObj class];
[classObject testName];
您不希望指向类对象(或实例)。 Objective-C运行时将取消引用您给它的指针,以便找到“isa”实例变量,该变量将是它所属的类。类对象的“isa”是“元类”,它包含类方法列表,因此类方法查找的工作方式。在你的例子中,它会取消引用指针并找到TestObj类,这意味着它认为它在TestObj实例上调用一个方法 - 当你没有 - 你还没有分配一个,但它实际上只是一个垃圾指针。但是,它仍将(完全运气)进入你的实例方法实现,但“self”并不是真正的有效实例。但是,它看起来就像值一样,恰好响应-name方法并返回带有该值的NSString或UIViewController实例本身。或者它可能正在尝试基于垃圾指针来引用实例变量,最后通过eventstance结束指向ViewController实例的指针。我认为这会尝试调用-name方法。
无论如何,tl; dr - 你的代码是完全错误的(不要使用&amp;类或实例的指针)你很幸运,你没有崩溃。 (桥头ID)演员隐藏了试图帮助你的警告。