Is there any way to access the address of a private instance variable of any class in the target c environment?

Is there a way to access the address of a private instance variable of any class using the c object runtime?

eg:

self.navigationItem.title 

Is there any way to get the _title ivar address of the UINavigationItem class?

thanks

+4
source share
2 answers

Obvious observations: self.navigationItem.title cannot be an instance variable, because a getter can do anything to generate a result, and a point designation just calls the getter. Even if it is an instance variable in this version of the OS, it may not have been in the past and may not be in the future. Even if the name is directly supported by the instance variable, it cannot be called _title - it could be called anything.

Even if you know for sure that the class has a specific instance variable, the corresponding mechanisms are removed from Objective-C 2.0. In an earlier version, you could use:

 #import <objc/runtime.h> ... Ivar instanceVariable = class_getInstanceVariable([instance class], "varName"); // yes, really, a C-style string NSLog(@"offset of that var is %d", instanceVariable->ivar_offset); 

Or similarly:

 struct exampleClassStruct { @defs(exampleClass); }; // this is now a struct with the same layout all the same instance variables // as exampleClass 

However, now you have encountered errors such as "Invalid @defs application in non-fragile ABI". So in conclusion: you cannot do what you want. Probably the closest thing is to use class_GetProperty , which - like dotted notation - doesn't care about memory layouts or doesn't have the same name or even really an instance variable. Otherwise, the get_InstanceMethod class (on the same page) can be used to get the C function pointer to the receiver.

EDIT: quick follow-up after the following alastair comment below: runtime provides id object_getIvar(id object, Ivar ivar) ( link ) and set equivalent, which are opaque ways to get and set instance variables in a particular class, given that their address is now hidden . They take Ivar, which you get from class_getInstanceVariable or object_getInstanceVariable , so probably will not perform any complex search and explain why you can still get Ivars, even if the associated structure now has no public members.

EDIT2: see discussion with alastair below; the final parameter object_getInstanceVariable and / or the result of ivar_getOffset may be useful for doing what you want, depending on your interpretation of the documentation. Assuming you accept the same read as alastair, then any of the following will do what you want (temporarily encoded):

 #import <objc/runtime.h> void *pointerToInstanceVariableA(id object, const char *variableName) { Ivar instanceVar = class_getInstanceVariable([object class], variableName); return (unsigned char *)object + ivar_getOffset(instanceVar); } void *pointerToInstanceVariableB(id object, char *variableName) { void *returnValue; Ivar instanceVar = object_getInstanceVariable(object, variableName, &returnValue); return returnValue; } 
+4
source

I have a view controller, and I need a property from the base class. This name has been identified as

 @property ( nonatomic, strong ) NSString *ModuleName; 

code to access it without any class knowledge

Code to get an instance of a custom view controller

  id viewCtrl = [appDelegate returnTestView]; 

now I get the value (without knowing any class)

  Ivar instanceVariable = class_getInstanceVariable([viewCtrl class], "ModuleName"); NSString *privateValue = (NSString *) object_getIvar(viewCtrl, instanceVariable); NSLog(@"Your value is %@", privateValue); 

Actual method in my appDelegate application

 - (id)returnTestView { return [[TestViewController alloc] init]; } 

Launching my custom view controller

 @interface TestViewController : UIViewController - (id)init { self = [super init]; if (self) { // Custom initialization self.ModuleName = @"Hello World"; } return self; } 
-1
source

All Articles