Working with the Objective-C / Cocoa namespace

I haven't found anything yet that pertains to my namespace question.

I am working on some AudioUnit plugins with Cocoa based GUIs. Plugins use a common library of UI classes (sliders, buttons, etc.) that are simply added to every Xcode project.

When I recompile and distribute updates, it is pretty much guaranteed that at least one UI class will be updated since the latest version. If the user runs an older plug-in before the updated plug-in, the old Cocoa classes are already loaded at runtime, and attempts by the plug-in to use older versions often fail one way or another.

I know frameworks are the intended solution, but overhead and backward compatibility issues are not ideal. I've prefixed all class names where possible, but what options should I ensure that each plugin contains unique class names for common UI classes?

Update:

The solution that I seem to be arriving is as follows:

  • Set the preprocessor compiler flag eg. OBJC_PREFIX=1

    ...

  • Create a header file to contain all class name overrides and conditionally include it in the header of every class you want to rename, e.g .:

    #ifdef OBJC_PREFIX  
    #include "CocoaPrefixHeader.h"  
    #endif  
    @interface MySlider : ... etc
    
          

  • Fill in the header file (in this case CocoaPrefixHeader) with something like the following:

    #define MySlider Prefix_MySlider  
    #define MyButton Prefix_MyButton  
    
          

  • Using ibtool, convert all the class names in the existing nib / xib file to new names, for example:

    ibtool --convert MySlider-Prefix_MySlider nibfile.xib --write nibfile2.xib  
    ibtool --convert MyButton-Prefix_MyButton nibfile2.xib --write nibfile2.xib
    
          

This last step will convert all class names and releases, etc. to the nib file. After the conversion, you can edit the thread as usual and IB keeps track of the overridden names.

The process is tedious and time consuming, but it works . It is much better to satisfy him from the beginning.

+2


a source to share


3 answers


While the solution I reached in the updated part of the question works as a final step in the project, I cannot recommend it for anything where your classes are in a state of change. I have not been able to add additional outputs to the classes and show them in IB for example.

I ended up just duplicating my classes and adding unique name prefixes for different projects. Using ibtool --convert to update the xib file made the process much faster.



Once things get low, maybe a framework idea is a better idea.

0


a source


In your precompiled header (.pch) file, you can #define

have different names for each plugin , for example:

#define ClassNameUsedInYourCode ClassNameCompiledInThisProject
#define WidgetButton WahWahPedalPluginWidgetButton

      



As long as you create your user interface programmatically, this ensures that the class names are unique for each plugin. Unfortunately this won't work if you have the class names baked into the nib files.

In that case, you probably need some kind of preprocessing script that is done before compilation and replaces any instances of common class names with project class names in all project files, including .xib files. This can get pretty messy, but I don't see too many options.

+2


a source


I had a similar problem. I needed to have more than one version of the same package running in the same app space at the same time (I can't even remember why). It wasn't easy, I discussed my problems and options on the Objective-C mailing list. At the end, I changed the build environment to:

  • Scan each header for classes declared with @interface

    .
  • Create a new header filled with only preprocessor macros that override class names from MyClass

    to MyClass_v1_00

    (or any version was defined in the Info.plist file). This title has been called ClassRenamer.h

    .
  • As an intermediate build step, parse all xib XML files and replace the references MyClass

    with MyClass_v1_00

    . This does not modify the original xib files, which is convenient.
  • Change the command line build flags to include ClassRenamer.h

    for all .m

    files.

Surprisingly, everything works fine, both at runtime and even in the debugger. If I put a breakpoint on a specific line, it breaks to whatever version of the loaded class, and Xcode even shows the class name as MyClass_v1_00

. The biggest problem is the code that looks for classes by name, i.e. Using NSClassFromString

.

+1


a source







All Articles