I have an idea on how to do this, but I want to make sure I do it right....
I have five data classes. When I use one I typically use all of them (but not always).
Each class has a separate header file. I am getting sick of linking in each header file separately.
What is the best way resolve this issue?
Create a new header file called "DataFiles.h". Inside that, have your five #import statements. Then whenever you need the file classes, just #import "DataFiles.h".
Beware of circular dependencies.
(This is how Cocoa, Foundation, UIKit, CoreData, etc all behave. Notice that you just #import <Cocoa/Cocoa.h>, which imports everything else. Open up Cocoa.h and take a look)
Related
I've noticed that while editing header files, XCode does not auto-suggest header files to import or classes from imported files unless the file you are editing is itself imported by some file that is included in the target.
I kind of get the reasons for this, but it's super lame. I'm very happy to take the trade off of disappointment at compile time (oops! that wasn't a class that I could import) for the benefit of saving a ton of time while writing headers.
By the way I'm aware that I can use forward class and protocol declarations but this is not helpful because I often need to use something whose name I've not committed to memory. Once I know the thing to forward-declare, then I will!
Is there any way to get XCode to be more liberal about this?
Edit: with pictures
Here's what I see in a header file included by an implementation file that is added to a target when I type the letters "#i":
Now I comment out the include of the header I was editing
Now here's what I get - but autocomplete still works
When I make a new protocol, of course it is not imported by some implementation file (because it is new and it is not a class, so there is no associated implementation file already created).
So autocomplete of imports (and classes) doesn't work... until I import it from an implementation
And now autocomplete works
So I am using the new #import module syntax introduced with the latest Xcode - I still wonder where the best place is to put them. Before, I would place library imports and very important categories in the .pch file, but now that's not necessary anymore (at least not for the native frameworks). My first idea was to create a modules.h file and do all the imports there, then include that modules.h file in the AppDelegate - but this doesn't seem right. Also, importing in the first place you need it doesn't make sense either, since you might use it in different places.
This is in fact a question about "best practices" which is - of course - a little subjective. But I think this affects a lot of people and the overall project structure. So please share your solution to this.
it sounds like you weren't doing it the best way before, In general you want as few symbols available at any one time. For a few different reasons:
less likely to make a mistake with symbols that have the same name but different values, or types... and for reasons that the compiler has to import less crap into each compilation unit.
I am not an expert on how #import has changed the compiler semantics of preprocessing and compiling, but I suspect you should still basically import things as close to the point that they will be used as possible.
I generally will not generally import any class's headers into another class's .h file.
in a .h I will forward declare any classes with #class SomeCLass and only include enough headers to satisfy the c/c++ types that I use as ivar/properties. The only exception to that being if I need to include a superclass's header or another .h for a protocol.
the rest of the includes go into the .m
I like to keep my pch pretty spartan, but if you have some utility categories or a widely used library you could include stuff in there, I tend not to... but in a smaller project you probably wont run into problems... you will run into indexing problems in projects with hundreds of source files, especially if you have some Objective-C++ units. That will end up hurting code completion and live syntax checking.
After several months of coding in Objective-C, I completely understand when I need an #import, how import statements cascade (ripple?), and when to use forwarding classes. I do not know how to aggregate imports to get them inside of <> instead of in quotes (although maybe that's just for frameworks)...
The problem is that I'm making a huge mess. I come from Java (and the heavy-handed IDE), so I just add imports as I see fit. Sometimes I add them to the interface, but since that's usually not necessary, I just add them to the top of the .m in question.
Today I started thinking: there must be some rules of thumb on how to organize this stuff. In fact, since Objective-C is a C superset, there are rules of thumb for everything, but I don't know them. How should I organize my imports? Particularly:
When should I import in the .m?
When should I import in the .h?
Should I create .h files just for the sake of importing them (i.e., header files that just have imports in them)? If so, any hints on organizing that?
This is just a general idea of what I'm trying to figure out.
The <....> syntax is indeed just for frameworks. That doesn't mean you shouldn't create a framework to contain the core logic of your application though. Often this is a useful thing to do if you:
a) Need to provide support for loadable bundles that want to invoke aspects of your application logic (the bundle links to the framework, so does your application)
b) Write multiple apps that share the same core logic
Your question is somewhat subjective and you will get developers who argues both ways, but a convention I follow is:
Never import class definitions in the .h file, unless you are subclassing it. Use forward #class directives for everything in the .h.
Only import class definitions into a .m as you find you need to use that class in the implementation.
Generally speaking, the .h does not need access to the class definition of its ivars, method arguments or return values. It only needs to know that they are classes, which is what #class allows you to do. It does need access to the class definition of anything you're subclassing, adding a category to, or (obviously) implementing a protocol for.
Forget about whether <...> is for frameworks or what. <...> checks the system header search path, while "..." checks the current dir in addition to. One thing to remember however, is that the <CoreFoo/CoreFoo.h> declaration is handled a little differently on the apple platform, but only as it relates to apple frameworks: CoreFoo.framework/Headers/CoreFoo.h is matched to CoreFoo/CoreFoo.h
When imports are inside <> instead of quotes, all this means is that you are importing something from a framework. In fact, when doing this, the import is typically in the style
#import <Foundation/Foundation.h>
The first Foundation, before the slash, is the name of the framework in question, and the second one is just a header file in that framework. That header file is just something like
#import <Foundation/NSObjCRuntime.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
...
#import <Foundation/NSURLHandle.h>
including every file from that framework. You can do this too, and isn't a bad idea for components that need multiple imports (although in that scenario, you may want a separate public interface)
For the other stuff, following the rule of thumb that you want stuff to know about as little as possible, you only want to put the import in the header file if it's necessary (like for an ivar or superclass) but really it's a matter of taste.
I was just wondering if I have the option to specify more than one set of class declarations and definitions in the same file, without breaking it up into multiple files.
I'm guessing this is just the sign to break it up, but I was just wondering out of curiosity.
Also, bonus, when including, what is the difference between #include and #import.
Yes. The only really vital division is that a file should only be imported or compiled, not both — that is, unless all the code you feed to the compiler is in main.m, you need to have at least one header and one implementation file. The header can contain all the interface details for everything in your program and the implementation file can contain all the implementation details and it will work just like if you had separate files. You can just stack the contents of the would-be files end-to-end. That's actually what the #import and #include directives do — they literally copy the contents of the included file into the place where the directive is written.
Of course, what we're talking about here isn't a good design for a program at all.
Yes you can do that.
#import has built-in checks to prevent including the same file multiple times (avoiding stuff like #ifndef __MYHEADER_H...)
Yes you can have multiple classes in a same file but i don't prefer it. Its a good habit/good design to have classes in different files. Helps a lot in re-usability.
#import ensures that a file is only ever included once so that you never have a problem with recursive includes. I think performance may go down if use #include.
I've not found anything that addresses my specific name space question as yet.
I am working on some AudioUnit plug-ins featuring Cocoa based GUIs. The plug-ins use a common library of user interface classes (sliders, buttons etc) which are simply added to each Xcode project.
When I recompile and distribute updates it is pretty much guaranteed that at least one user interface class will have been updated since the last release. If the user launches an older plug-in before an updated plug-in then the old Cocoa classes are already loaded into the run time and the plug-in attempts to use the older implementations - often resulting in a failure one way or another.
I know frameworks are the intended solution but the overhead and backwards compatibility issues are not ideal. I prefix all class names where possible but what options do I have to ensure that each plug-in contains unique class names for the shared user interface classes?
Update:
The solution I seem to be arriving at is as follows:
Set a preprocessor compiler flag e.g. OBJC_PREFIX=1.
Create a header file to contain all the class name redefinitions and conditionally include it in the header of each class you want to 'rename' e.g:
#ifdef OBJC_PREFIX
#include "CocoaPrefixHeader.h"
#endif
#interface MySlider : ... etc
Fill the header file (in this case CocoaPrefixHeader) with something like the following:
#define MySlider Prefix_MySlider
#define MyButton Prefix_MyButton
Using ibtool convert all your class names in an existing nib/xib file to the new names e.g:
ibtool --convert MySlider-Prefix_MySlider nibfile.xib --write nibfile2.xib
ibtool --convert MyButton-Prefix_MyButton nibfile2.xib --write nibfile2.xib
This last step converts all class names and outlets etc in the nib file. Once converted you can edit the nib as normal and IB keeps track of the redefined names.
This process is tedious and laborious but it is working for me. Far better to cater for it at the outset.
In your pre-compiled header (.pch) file for each plug-in, you can #define the classes to have different names, e.g.:
#define ClassNameUsedInYourCode ClassNameCompiledInThisProject
#define WidgetButton WahWahPedalPluginWidgetButton
As long as you're creating your UI programmatically, this will ensure that the class names are unique per-plugin. Unfortunately this won't work if you have class names baked into nib files.
In that case, you'd probably need to have some sort of pre-processing script that runs before compilation and replaces any instances of the shared class names with the project-specific class names in all files in the project, including the .xib files. This could get pretty messy but I can't see too many options.
I had a similar issue. I needed to have more than one version of the same bundle running in the same application space at the same time (I can't even remember why). It was not easy, I discussed my problems and options on the Objective-C mailing list. In the end, I modified the build-environment to:
Scan every header for classes declared with #interface.
Create a new header filled with only preprocessor macros that redefine classnames from MyClass to MyClass_v1_00 (or whatever version was defined by the Info.plist file). This header was called ClassRenamer.h.
As an intermediate build step, parse all xib XML files and replace references of MyClass to MyClass_v1_00. This doesn't modify the original xib files, which is handy.
Modify the command-line build flags to include ClassRenamer.h for all .m files.
Surprisingly, everything works perfectly, both at runtime and even in the debugger. If I put a breakpoint on a particular line, it breaks on any version of the class that is loaded, and Xcode even shows the class's name as MyClass_v1_00. The biggest concern is code that looks up classes by name, i.e. using NSClassFromString.
Whilst the solution I arrived at in the updated part of the question works as the final step in a project I can't recommend it for anything where your classes are in a state of flux. I was unable to add additional outlets to classes and have them show up in IB, for example.
In the end I just duplicated my classes and added unique name prefixes for different projects. Using ibtool --convert to update the xib file made this process a lot faster.
Once things settle down maybe a framework will be a better idea.