Add metadata to Objective-C methods and properties - objective-c

How can I add additional, custom information to my objective-c methods and properties? I want to retrieve this metadata later on at runtime.
I know objective-c doesn't directly support method attributes, like in C#, but this is what I'm looking for:
[MyCustomAttribute(true)]
public void MyAwesomeMethod(int arg) {
// ...
}
The closest thing I recently found was a #define in the UIKit header files called UI_APPEARANCE_SELECTOR. Apparently Apple tags certain methods with this to be read later on.
Methods and properties are then define like this:
#property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR;
- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics UI_APPEARANCE_SELECTOR;
Can someone explain exactly how this works?
Thank you!

There's no inbuilt support for tagged metadata (attributes in .NET, annotations in Java, etc.) Apple's macro here is solely for the benefit of their developer tools, and you can't create your own that have any meaning past the preprocessor.
GCC/LLVM define some attributes that can be attached to various symbols. For instance, you can mark a method as deprecated by tagging it with __attribute__((__deprecated__)) but there's still no way to make a meaningful custom attribute.
If you tell us what you're trying to accomplish, maybe we can suggest an alternate approach to the problem.

Related

What is the naming convention for methods you know will appear in a later SDK?

I realize that there is some subjectivity in the question, but considering that Apple development is pretty opinionated about naming conventions I want to do this in the way that others will understand what my coding is doing. I am trying to ask the question in the most generic way, But I'll add some of my specific details in the comments in case it affects your answer.
Let's say that I am supporting both iOS 6 and iOS 7. There is a new method on an existing class that only exists in the iOS 7 SDK. Assume that implementing the functionality in a way that is "good enough" for my app is fairly straightforward. But, of course, I'd rather use the SDK version as it is likely to be better supported, more efficient, and better handle edge cases.
As documented in this Q&A it is straightforward to handle this situation.
if ([myInstance respondsToSelector:#selector(newSelector)]) {
//Use the SDK method
} else {
//Use my "good enough" implementation.
}
But I don't want to litter my code with a whole bunch of conditional invocations. It seems that it would be better to encapsulate this dynamic method selection. (Especially in my case, where the method hasn't actually shipped yet and the name/signature might change.)
My instinct is to add a class category that implements both my functionality as well as a wrapper method that implements this dynamic selection of method.
Is this the right approach? If so, what naming conventions should I use? (I obviously can't name my method the same as the iOS7 method or there would be naming collisions.)
My gut reaction is to call my wrapper method safeNewSelector and my implementation a private method called lwNewSelector (where lw is my standard class prefix). But I'd much rather use something that would be considered a standard naming convention.
My instinct is to add a class category that implements both my functionality as well as a wrapper method that implements this dynamic selection of method.
That sounds right. The naming convention for category methods is a lowercase prefix, plus underscore. So, if you are shadowing a method called doSomething:withAwesome:, you would name your category method ogr_doSomething:withAwesome: (assuming you use OGR as your common prefix).
You really must prefix category methods. If two categories implement the same method, it is undefined behavior which will be run. You will not get a compile-time or runtime error. You'll just get undefined behavior. (And Apple can, and does, implement "core" functionality in categories, and you cannot easily detect that they've done so.)
Go for a category and chose a name that is pretty unique, for example prefixed by some company/project specific prefix. Let's say the method in iOS 7 is going to be called funky and you chose the prefix foo. Then you'd do:
#implementation SomeClass(FooCategory)
- (void)foo_funky
{
if ([self respondsToSelector:#selector(funky)]) {
[self funky];
} else {
// Implementation of workaround.
}
}
#end
Now, every time you'd call foo_funky that decision needs to be made. Pretty inefficient. It just occurred to me that Objective-C can make that more efficient by messing with the runtime, kind of like method-swizzling (following code is untested):
#implementation SomeClass(FooCategory)
- (void)foo_funky
{
// Empty implementation, it will be replaced.
}
- (void)foo_myFunkyImplementation
{
// Workaround implementation in case the iOS 7 version is missing.
}
+ (void)load
{
Method realMethod, dummyMethod;
realMethod = class_getInstanceMethod(self, #selector(funky));
if (!realMethod) {
// iOS7 method not available, use my version.
realMethod = class_getInstanceMethod(self, #selector(foo_myFunkyImplementation));
}
// Get the method that should be replaced.
dummyMethod = class_getInstanceMethod(self, #selector(foo_funky));
// Overwrite the dummy implementation with the real implementation.
method_setImplementation(dummyMethod, method_getImplementation(realMethod));
}
#end
This way every time you call foo_funky the correct method is called without the overhead of responds-to-selector-and-then-call-other-method.
You could also use the runtime class modifications to add your implementation using the official name when it's not available, but I don't recommend that. It's better when you can tell by the method name that it might not be the version you're expecting.
It is a fair question indeed and I think many Objective-C debs have run into this situation.
I have used the approach that you suggest, using a class category, in several places myself. As for the naming, in most cases I put a little extra functionality into my category method, so my method names most of the time take another argument – in most cases a simple animated:(BOOL)animated added to the end of the "official" method name.
Yes, there's a risk of clashing with future SDK releases, but I wouldn't worry too much about it, Xcode's refactoring works reasonably well and you'll get a linker warning when category methods conflict.
Edit:
As Rob points out, using that naming convention is probably a good idea.

Header files without implementation

I'm working on a open source project, which consist on a framework for iOS devices, and one of the methods is not working as I expected. I tried to search for the implementation of the method, but all I found was a a header file and the method declaration; I didn't find the implementation anywhere. Neither did I find the .m file corresponding to that class.
So I have some questions:
How can a class exist without it's implementation and still its methods perform certain operations?
What is the purpose of writing this kind of classes.
In this kind of situations where should be the methods implemented?
Note
The open source project is FastPdfKit and the method is wholeTextForPage:
Well, those methods are somewhere, so it's not that they don't exist, you just can't see them.
Try for example to open UITableView.h, you can see the methods definition, but not the implementation. The implementation is hidden in the library, but you can't see it.
In a nutshell, developers do this to hide the details of the implementation of a class to other users. You just receive a header that tells you which methods you can use, and how, but the details about how are they implemented are hidden for you.
For example, Apple doesn't want you to see how they implemented UITableView, but they want you to know how you can use it.
Here you can find a tutorial about how to create a library for Objective-C:
Creating Static Libraries for Objective-C

Objective-C convention for overridden methods

In Java, when you override a method, you are advised (almost forced) to add the #Override annotation. Is there a convention to mark (either in comments, or by some other mechanism) overridden methods in the Objective-C world?
No. All methods in Objective-C are sent via Objective-C's messaging, so all methods can be overridden. That's part of the language.
There's no convention for marking this, either. It's part of the language that it happens, and if you were to comment otherwise it'd just be confusing when you did it later, accidentally or intentionally.
I'm not sure if Xcode does this, but the AppCode IDE from Jetbrains automatically annotates overridden methods with the little blue override badge in the margin, like so:
. . further to that (also shown), I also like to create some live templates (aka code-snippets in Xcode) to annotate overridden methods with a #pragma tag. I find that it helps to define a standard structure in this order:
class methods
initialization & destruction
public methods / protocol methods
overridden methods
private methods
and by having Live Templates/Code Snippets I can just type 'override [tab]' and the IDE will create the #pragma tag for me.
. . perhaps you could even use OCLint to check that this structure is adhered to.
No, not really.
It doesn't seem to matter as much, probably because of the dynamic dispatch.

Using Objective-C Metadata to Generate Class Dependency Graph

This guy came up with a pretty neat tool to generate a class dependency graph - however, it relies on parsing your source code and looking for #import directives.
http://seriot.ch/blog.php?article=20110124
https://github.com/nst/objc_dep/blob/master/objc-dep.py
This is neat, but I have a number of problems with this. Not least of which is it doesn't take into account imports of imports nor prefix headers nor whether-or-not the class(es) in the file referenced by the import are actually being used.
I'd like to do something more akin to class-dump and examine the Objective-C metadata stored in the Mach-O file to generate an in-memory representation of the class dependencies.
I'd rather not do this from scratch, so I'm wondering:
Has it already been done?
Is there an open-source library which would provide me with the foundational tools I need to extract this information (a library which examines the Mach-O file and creates a façade of the Objective-C information contained within - such that I could iterate over all of the classes, their methods, properties, ivars, etc and scan for references to other classes) I figure class-dump's source would be a good place to start.
If you have experience in this sort of thing, is what I'm trying to accomplish feasible?
What roadblocks will I need to overcome?
Has it already been done?
Not that I know of.
Is there an open-source library which would provide me with the
foundational tools I need to extract this information?
At the core of class-dump is libMachObjC which does exatly what you want, i.e. parse all classes/methods/ivars and more. The API is very clean, it should be very easy to use.
If you have experience in this sort of thing, is what I'm trying to
accomplish feasible?
Unfortunately, no because some classes don't declare the real class but use id instead. For example, here is the information that can be extracted from a class-dump of UIKit:
#interface UITableView : UIScrollView <NSCoding>
{
int _style;
id <UITableViewDataSource> _dataSource;
id _rowData;
...
The _rowData ivar type information is id but if you check at runtime you will see that _rowData is an instance of the UITableViewRowData class. This information is not present in the Mach-O binary so you have no way to find the relation between UITableView and UITableViewRowData. The same applies for method parameters.
Here's a solution that relies on information in mach.o files, and generates graph dependency based on that information: https://github.com/PaulTaykalo/objc-dependency-visualizer
Has it already been done?
yes - but i can't recommend a good public implementation
Is there an open-source library which would provide me with the foundational tools I need to extract this information (a library which examines the Mach-O file and creates a façade of the Objective-C information contained within - such that I could iterate over all of the classes, their methods, properties, ivars, etc and scan for references to other classes) I figure class-dump's source would be a good place to start.
most use cases would benefit by using the objc runtime facilities objc/... rather than examining the binary.
If you have experience in this sort of thing, is what I'm trying to accomplish feasible?
yes. i've done something similar using the objc runtime.
What roadblocks will I need to overcome?
that depends largely on the level of detail you want... implementation time if you find no such implementation, but i figure you will find a few options if you google the more esoteric functions in the objc runtime; perhaps you would find one in an (open) language binding or bridge?
if you do end up writing one yourself, you can get registered objc classes using objc_getClassList, then access the properties/information you want from there.

Xcode: Possible to auto-create stubs for methods required by Protocol interface?

Coming from an Eclipse / Java background, one of my favorite features is the ability to quickly stub out all the methods required by an interface. In Eclipse, I can choose 'Override / implement' from the source menu to generate stub methods for any method of the Interface.
I'd like to do the same thing in Objective-C. For instance, if I declare a class that implements the 'NSCoding' protocol, I'd like to have Xcode automatically generate the methods required to implement this Protocol. It's frustrating to have to look-up and then copy/paste the signatures of the required methods every Protocol that I'm trying to implement.
I've been trying for awhile to find out if this is possible, but haven't found anything promising yet. Is this possible in XCode?
I believe that Accessorizer will do what you want.
Accessorizer will write the encode and decode methods for ivars passed to it (NSCoding protocol and for NSDocument archiving). It will also generate string constants either static or #define with a custom prefix; copyWithZone:; and other things if you need - all from a simple shortcut via Services or from the toolbar. Accessorizer keyed archiving
Not the direсt answer, just hint:
Out of the box XCode can't.
But AppCode can.
It can do this things automatically (with your permission, of course).
If some methods of protocol marked as #required - AppCode will highlight the implementation and suggest to implement this methods.
#optional methods also available to implement automatically (shortcut: control + I).
Your can create scripts for the scripting menu item in AppleScript, Perl, Python, Ruby, or any other scripting language that go in the scripting menu.
Your could place the insertion point in the .m file and have the script look up the corresponding .h file. Locate the protocols supported and so forth...
MacTech ran an article in 2007 Xcode Menu Scripts
Xcode 3.2 will autocomplete known method implementations. In other words, if the method is declared somewhere (for example, in a protocol), when you start to type it in a .m file, Xcode 3.2 will autocomplete the method signature for you. This isn't quite what you asked for, but it is awfully handy.
I'm also looking for a way to generate method stubs for the protocols in my header file. I checked out Accessorizer and it looks to be a handy tool but unless I missed something I didn't find a way to get it to generate method stubs for a protocol.
Eric, If you found another solution please post what you found. It's amazing to me that XCode doesn't already have this built into the IDE.
Since the accepted answer's given link does not work anymore (and is redirected to an ad), here's another good explanation on how to use accessorizer to create protocol method stubs.
Based on AllanCraig's "Create #property, #synthesize & dealloc from Variable Declaration" ruby script, I made one to generate implementation stubs from interface ones: http://pastebin.com/4T2LTBh6
How to use?
Setup the script on your XCode (Shell Script) and assign a shortcut for it (e.g. CMD+5).
Select lines from your interface file in which you want to generate the implementation, and press the hotkey.
Your .m will contain your selected methods.
I know this is an old question but if you'd like to always see the latest definitions just right click on the class in question and Jump to Definition. Here lyes all the current non-deprecated functions so you aren't relying on a 3rd party to stay up to date.
In My case Below style helps me much, In a sense solved my problem.
Suppose you have following method declaration:
+(DBManager*)getSharedInstance;
From Implementation file you start typing +ge and xcode will automatically choose method
+(DBManager*)getSharedInstance;