Can I do NSVariableFromString like NSClassFromString and NSSelectorFromString? - objective-c

Right so I have noticed that you can do NSClassFromString and NSSelectorFromString.
Is it possible to do something like NSVariableFromString?

No. Compiled applications don't contain variable names except when debug info is included and it usually isn't for release applications.

The objective C runtime has lots of goodies for your consumption.
If you want an iVar, you can call object_getInstanceVariable with a string name.
If you want variables, it's a bit more work, and they have to be globally visible to the linker. You can use CFBundleGetDataPointerForName for that purpose.
Be sure to read the documentation for restrictions and specific information about runtime information, and the availability of stuff on different platforms.

You can get values from strings using NSScanner but, as JemeryP notes, at runtime variable names have generally been converted to pointers and memory addresses.

Related

Bridge to objc, how can it knows arguments types?

I am writing a bridge from a language I am developing and ObjC.
There are several nice introspection C functions in the objective C runtime and I am able to retrieve arguments types for methods using method_getTypeEncoding.
The main problem is with object arguments which are returned as id (encoded as #) but what I would need is the real objc class name like NSString or NSNumber.
Is there a way to solve this issue without parsing the .h files?
Knowing something is an id allows you to know the size of the parameter, which is important when writing a scripting interface. Add another layer where you can dynamically verify assumptions using things like
[objectPassedIn isKindOfClass: [expectedType class]];
You want to be careful hardcoding things like, "Oh this is a string so look for __NSCFString" - because there's no way to know you'll get an instance of __NSCFString or another type. NSString is a class cluster - You could get any custom implementation back when using one.
The actual type of objects is not important to the Objective-C Runtime so you need to add your own layer. You might be able to get some useful info using Clang/llvm as a tool.

How are data members stored in an object?

I know that in Objective C, every object has first 4 bytes [depending upon type of processor ] as an isa pointer stored in it that tells which class it belongs to and what dispatch table to use to resolve a selector to address of a function.
What I wanted to know was , how are data members stored and accessed in these methods.
self is passed as an implicit object in each function being called.
We use setters n getters to handle data members in other member function as a good practice,
but when we directly refer to a data member in an initializer or an accesor, how are they accessed. Are they replaced by some address at compile time or something else ?
Actually afaik the memory layout is implementation specific, but http://algorithm.com.au/downloads/talks/objective-c-internals/objective-c-internals.pdf should give you a pretty good idea of the inner works of object data and object messaging.
When you use a direct member access, what basically happens is that you're fetching straight from the "struct" that is your actual object. That is, the compiler is basically just adding an offset to the address of your object/struct and reading the contents of that memory address.
Maybe I should add that this is reverse engineered from XCode and not written in any specification I can find, so depending on this behavior is most likely a bad idea. Since external access to the iVars is not allowed, the decision is basically up to the compiler and could be changed at any time.
Edit: as #FrederickCheung points out, Objective C 2.0 may have changed this behavior.
It's not as simple as a compile time offset calculation, at least not in objective C 2.0 on the 64bit OS X and iOS runtimes. These support stuff like superclasses changing their instance variable layout without breaking subclasses that were compiled against the old layout by adding a layer of indirection.
The runtime api docs describe the API one can use to set instance variables and so on but doesn't elaborate on their implementation.

Use of __attribute__'s in ARC-managed Code

When ARC came to Objective-C, I did my best to read through the Objective-C Automatic Reference Counting (ARC) guide posted on the Clang project website to get a better hang of what it was about. What I found there (and no where else) was mention of using __attribute__ declarations to signify to ARC whether certain code autoreleases its return value, for instance (__attribute__((ns_returns_autoreleased))), or whether it 'consumes' a parameter (__attribute((ns_consumed)), and so on.
However, it seems that the guide gives very little word on the actual level of necessity these declarations hold. Excluding them seems to make no difference, neither when running the static analyzer nor when running the project itself. Do these even make a difference? Is there any advantage to labeling a method with __attribute__((objc_method_family(new)))? No article I've found on ARC makes mention of these specifiers at all; perhaps an ARC guru can give word on what these are used for.
(Personally, I include all relevant specifiers just in case, but find that they make code obfuscated and messy.)
These attributes are expressly for abnormal cases, such as:
A function or method parameter of retainable object pointer type may be marked as consumed, signifying that the callee expects to take ownership of a +1 retain count.
A function or method which returns a retainable object pointer type may be marked as returning a retained value, signifying that the caller expects to take ownership of a +1 retain count.
You don't normally do these things, so you don't normally use these attributes. With no attributes, the normal behavior—the NARC rule, or perhaps under ARC I should say CAN—is what the compiler implements and expects.
There are two reasons to use these attributes:
In order to violate the CAN rule; that is, to have a method not so named that returns a reference, or a method so named that doesn't. The attribute documents the violation in the method's prototype, and may even be necessary to implement it, if the implementation uses ARC.
Working with Core Foundation types, including Core Graphics types. These aren't ARCed, so you need to use the bridging attributes to aid conversion to and from “retainable object pointer” types.
That's not necessary in most of the cases, since LLVM & Clang knows ObjC naming conventions. So if you follow the standard naming conventions of Cocoa, LLVM automagically assumes the corresponding family/return memory policy to follow.
Namely, if you declare a method named initWith... it will automatically consider it as the "init" family of methods, no need to specify __attribute__((objc_method_family(init))), Clang automatically detect it; same for the new family, etc.
In fact, you only need to use the __attribute__ specifiers when Clang can't guess such cases, which in practice rarely occurs (in practice I never had to use it), or only if you don't respect naming conventions:
Quoting Clang Language Extensions Documentation:
Many methods in Objective-C have conventional meanings determined by their selectors. For the purposes of static analysis, it is sometimes useful to be able to mark a method as having a particular conventional meaning despite not having the right selector, or as not having the conventional meaning that its selector would suggest. For these use cases, we provide an attribute to specifically describe the method family that a method belongs to.
So as soon as you respect the naming conventions (which you should always do) you won't have anything do to.
You should definitely stick to naming conventions wherever possible.
It's clearer to read.
Attributes can introduce build errors if there is a conflict.
ARC semantics combined with attributes are relatively fragile.

Is it possible to replace malloc on iOS?

I'd like to use a custom malloc and free for some allocations in an iOS app, including those made by classes like NSMutableData.
Is this possible?
If so, how do I do it?
What I'd actually like to do is zero out certain data after I've used it, in order to guarantee forward security (in case the device is lost or stolen) as much as possible. If there's an easier way to do this that doesn't involve replacing malloc then that's great.
I believe I need to replace malloc in order to do this because the sensitive data is stored in the keychain --- and I have no option other than to use NSDictionary, NSString and NSData in order to access this data (I can't even use the mutable versions).
Instead of overwriting generic memory management functions you can use custom allocators on the sensitive objects.
The keychain services API is written in C and uses Core Foundation objects, like CFDictionary, CFData and CFString. While it's true that these objects are "toll free" bridged to their Objective-C counterparts and are usually interchangeable they have some abilities not available from Objective-C. One of these features is using custom allocators.
CFDictionaryCreate for example takes an argument of type CFAllocatorRef which, in turn, can be created using CFAllocatorCreate. The allocator holds pointers to functions for allocation and deallocation, among others. You can use custom functions to overwrite the sensible data.
Why do you need to go so low-level about it? I'd just overwrite the data in the NSMutableData instance with zeroes instead. If you really need to mess with malloc - I'd probably write a category on NSObject and override the memory-handling functions.
Disclaimer: I have no iOS experience, but I understand that it uses GCC. Assuming that is correct...
I have done this, albeit with GCC on the PlayStation3. I don't know how much of this is transferable to your case. I used the GCC objcopy utility with --weaken-symbol. (You may need to use nm to list the symbols in your library.
Once you've "weakened" the library's malloc, you just write your own, which is then used instead of the original when linked (rather than giving you a link error). To delegate to the original you may have to give it another name somehow (can't remember -- presumably doable with one of the binutils or else there's both a malloc and a _malloc in the library -- sorry, it's been a while.)
Hope that helps.
I'd encourage you to use the Objective-C memory management system based on ownership (retain/release). Memory Management Programming Guide
Another option would be to use C structures with C memory management rules like malloc.
NSMutableData methods like dataWithBytes:length use calloc / bzero internally already. Is that good enough for you?

GNU Objective-C runtime trickery

Can I, in the GNU Objective-C runtime, attach semi-arbitrary pieces of data to instance variables?
Challenge:
I'm currently working on a kind of Cocoa workalike for Linux, as a sort of pet project. (Please, let's not get sidetracked by all the "use GNUStep" stuff. I know about it, but it doesn't suit my needs. Moving on…) For this purpose I'm trying to cobble together a simple ORM system, reminiscent of DBIx::Class for Perl. The general idea is to make the declaration as simple (read: short) as possible, and if at all possible, without the need to provide +(id)constantClassAttribute methods for overriding.
The general idea is to declare my result classes as follows:
#interface SomeTable : ORMResult {
unsigned long long id;
ORMResult *toOneRelation;
ORMResultSet *toManyRelation;
}
#end
So far, so hoopy. I can now access these fields using [ORMResult self]->ivars, and do all manner of nasty stuff, like automagically generating accessors like -[toManyRelation] or -[setToOneRelation]. Piece of cake. Unfortunately, there are two pieces of information I cannot add using this setup; one is simple enough to solve, the other not so much:
What is the actual result class?
This is solved by subclassing ORMResult (like SomeTable), and plugging that in
there, using runtime dynam(ag)ics to figure out it's to-ness (toMany, toOne).
(And this is the tricky one!) Is the relationship nullable?
This is less easily solved. My initial ideas were
(ab)using protocols, like so:
#interface SomeTable : ORMResult {
unsigned long long id;
ORMResult <ORMNullable> *toOneRelation;
}
#end
This compiles, but unfortunately, when I try to use GDB to inspect the
ivars->ivar_list entries I find that the protocol information isn't actually kept
for the runtime to toy with. This makes, I suppose, some kind of twisted sense,
as protocol declarations are mostly for the compiler.
Abusing the protocol identifiers (byref, bycopy and friends, using defines:
#interface SomeTable : ORMResult {
unsigned long long id;
nullable OMRResult *toOneRelation;
}
#end
This has the rather obvious drawback of not actually working, as these
specifiers apparently only work in protocol method declarations.
The question, then, is how can this attachment of information to the ivars be pulled off in practice?
Note: As mentioned initially, I'm using the GNU Objective-C runtime, as supplied by GCC on Linux; and not the one supplied by Apple!
Edit: Starpox! I forgot a central point: An alternative, of course, is to simply make all relations nullable. This I don't really want, but if no other alternative exists, I guess that's the path I'll end up going down.
Well, how we used to do this in ye olde days on the Mac was to create a global variable holding an NSMutableDictionary into which we put the data we want to attach to an object. Simply use a string representation of the pointer as the key.
The only difficulty becomes figuring out when an object has gone away and making sure that its entry in the dictionary is removed as well. You may have to resort to hackery like method swizzling -dealloc to achieve that.
You might look at objc_setAssociatedObject and friends, which allow you to attach arbitrary data to an object. However, I'm not sure if they're supported in the version of libobjc that you're running.