iOS类方法

时间:2016-09-30 03:26:51

标签: ios objective-c runtime

@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?

感谢。

1 个答案:

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