2016-09-30 44 views
4
@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 

日志:的iOS类方法

name: <ViewController: 0x7ff3584b6580> 

我的理解是vid是一个指向TestObj类对象的地址,那么为什么vid可以直接发送到testName实例方法?

另外,为什么testName方法调用NSLog将输出<ViewController: 0x7ff3584b6580>而不是零?

谢谢。

+0

真的很奇怪,您可以在指向类的指针上调用实例方法。如果将'testName'更改为类方法而不是实例方法,请参阅会发生什么情况。 – rmaddy

+0

- [TestObj testName]:发送给实例的无法识别的选择器 – WENHUI

回答

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实例上的一个方法,当它不是 - 你没有分配一个,但它实际上只是一个垃圾指针。但是,它仍然(通过完全运气)进入你的实例方法实现,但“自我”并不是真正的有效实例。但是,它看起来像任何值,只是响应一个-name方法并返回带有该值的NSString或UIViewController实例本身。或者,它可能试图基于垃圾指针来引用实例变量,并通过碰撞实例来结束指向ViewController实例的指针。我认为那会尝试调用一个名称的方法。你的代码是完全错误的(不要使用&类或实例的指针),你只是幸运的你不会崩溃。 (桥ID)演员隐藏了试图帮助你的警告。