@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?
谢谢.
最佳答案 我认为你基本上很幸运,你没有崩溃的代码.
首先,类方法以不是 – – 开头,因此这是您正在实现的实例方法.
@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 – 你的代码是完全错误的(不要使用&类或实例的指针),你很幸运,你没有崩溃. (桥ID)演员隐藏了试图帮助你的警告.