WENHUI
WENHUI

Reputation: 71

iOS Class Method

@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

log :

 name: <ViewController: 0x7ff3584b6580>

My understanding is vid is a pointer to the address of the TestObj class object, then why vid can be sent directly to the testName instance method?

Also, why the testName method calls the NSLog will output <ViewController: 0x7ff3584b6580>instead of nil?

Thank.

Upvotes: 4

Views: 136

Answers (1)

Carl Lindberg
Carl Lindberg

Reputation: 2972

I think you are basically getting lucky that you aren't crashing with that code.

First, class methods start with a + not a - -- so that is an instance method you are implementing.

@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];

You don't want to take pointers to class objects (or instances either). The Objective-C runtime will dereference the pointer you give it, in order to find the "isa" instance variable, which will be the Class it belongs to. The "isa" of a class object is the "meta-class", which contains the list of class methods, so that is how class method lookup works. In your example, it would dereference the pointer and find the TestObj class, meaning it is thinking it is calling a method on a TestObj instance when it's not -- you have not allocated one, but it's really just a garbage pointer. But, it will still (by complete luck) get into your instance method implementation, but "self" isn't really a valid instance. However, it looks like whatever the value is, just so happens to respond to a -name method and return either an NSString with that value or the UIViewController instance itself. Or maybe it's trying to deference the instance variable based on the garbage pointer and ending up with a pointer to the ViewController instance by happenstance. I think that would try to call a -name method though.

Anyways, tl;dr -- your code is quite wrong (don't use & pointers of classes or instances) and you are just getting lucky you aren't crashing. The (bridge id) cast is hiding the warning which was trying to help you.

Upvotes: 1

Related Questions