iOS类方法

@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)演员隐藏了试图帮助你的警告.

点赞