
What is the best way to solve an Objective-C namespace collision? - pooriaazimi
http://stackoverflow.com/q/178434/347353
======
SeoxyS
This situation is most commonly encountered on iOS, with ad networks and
SBJson.

As the developer behind one of the ad network SDKs included in countless iOS
apps, I struggled finding a good solution to this problem. Spoiler: there
isn't one.

The good news is, while there were often collisions on SBJson; pretty much all
versions of the version are compatible. For a while, we would compile our
static library without the SBJson objects, and ship the library and SBJson
separately.

Recently we decided to create our own fork of SBJson, and switch to using our
own prefix, which allowed us to embed it in our library, and not worry about
what other libraries were doing.

Note: another tricky gotcha with static libraries for iOS: There is a bug in
the linker, in that it will not import Objective-C categories from `.o` files
unless there is another another symbol that is recognized, such as a class of
C function. This has caused crashers and much headache.

~~~
thought_alarm
Namespaces don't really solve that problem, do they?. Your options are to
either fork SBJson and give it its own namespace/prefix, or require SBJson as
an external dependency and lets your users provide their own version of the
framework.

~~~
wsc981
I prefer if SBJSON is an external dependency, since there's less chance that I
need to modify external projects my own projects make use of. The downside of
course is that not all external projects might use the same version of SBJSON,
so method names could have changed, could be missing, etc... So it falls to
the developer to provide patches to external libraries if they use an outdated
version of a library like SBJSON.

Still, this is for me the preferred approach.

------
buddydvd
I'm not sure how well this works, but Nimbus (iOS framework) lets you embed
itself in your own static library with a custom prefix via preprocessor
macros. It would helpful if more libraries provide this feature.

<http://wiki.nimbuskit.info/Nimbus-Namespacing>

~~~
barumrho
This file seems to do the trick. Using macros to override class names.
[https://github.com/jverkoey/nimbus/blob/master/src/core/src/...](https://github.com/jverkoey/nimbus/blob/master/src/core/src/NimbusCore%2BNamespace.h)

~~~
pooriaazimi
I'm getting more confused. Using #if... requires recompilation, doesn't it? So
how can a library use them?

Now that I think about it, I see that I don't have any idea how 'dylib's
work... I should look them up.

~~~
buddydvd
If you are building your own static library and would like to distribute
Nimbus with it, this feature allows you to add a prefix to all Nimbus classes
without having you to manually rename them. This lets users of your static lib
free to include Nimbus with their project without triggering a name conflict
with the one included with your lib.

------
sjmulder
A month ago, Kyle Sluder proposed a namespacing system for Objective-C[1].
There has been a lively discussion both in the comments and on the objc-
language mailing list[2].

1: [http://www.optshiftk.com/2012/04/draft-proposal-for-
namespac...](http://www.optshiftk.com/2012/04/draft-proposal-for-namespaces-
in-objective-c/)

2: [http://lists.apple.com/archives/objc-
language/2012/Apr/msg00...](http://lists.apple.com/archives/objc-
language/2012/Apr/msg00000.html)

~~~
aufreak3
This is interesting, but doing it all at the compiler and language level seems
like overkill. ObjC is a dynamic language, so the important thing is to have
namespacing support in the _runtime_. If the _user_ of a framework or bundle
can specify a (reified) namespace to load a bundle's classes/protocols/etc and
the runtime and language support A.B.C style class and protocol names, that
might be enough to solve name collision problems. The framework/bundle
_author_ need not then bother to find a suitable globally unique name. This
would certainly be enough to solve the original poster's problem.

I'm not sure I've thought through all issues with the above approach, but the
whole @namespace thing seems gross overkill to me.

------
cageface
As ugly as C++ namespace mangling is, it does seem preferable to the kind of
hacks it takes to solve this problem.

On the other hand, with a carefully chosen three letter prefix these kinds of
collisions should be pretty rare in practice.

~~~
fleitz
Java/C# solve this problem, yet in those languages it's possible for one
compiler's code to link with another.

Namespace mangling and more importantly a lack of standard for it are not
required to implement namespaces.

In Obj-C it really wouldn't be that difficult to make an @namespace directive
that just prepended the namespace to the class.

    
    
      @namespace com.apple.foo
      @interface Bar : NSObject
      @end
    

Could be semantically equivalent to

    
    
      @interface com_apple_foo_Bar
      @end

~~~
cageface
If you're running in a virtual machine you have a lot more flexibility to
solve these kinds of problems, of course.

I wouldn't mind seeing explicit namespace support in Obj-C although I can't
say I've run into any namespace clashes in my own code yet.

~~~
pjmlp
> If you're running in a virtual machine you have a lot more flexibility to
> solve these kinds of problems, of course.

Why so? Since the late 70's every language that supports modules has already
solved this problem, and many of them have native code compilers.

~~~
cageface
In a vm you can do dynamic loading and bytecode manipulation tricks that are
much harder to do in native code. Look at all the crazy AOP stuff people have
done on the JVM.

~~~
pjmlp
You can do the same in native code, it just a bit harder to do.

That is how you do cool demoscene stuff in 4096K or less, with lots of self
rewriting code.

------
pjmlp
Funny how Apple still relies on language without any form of namespace support
for their system.

Prefixes are not a solution as they have no ways to avoid collisions.

So much for supporting large scale development with Objective-C.

~~~
batista
> _Funny how Apple still relies on language without any form of namespace
> support for their system._

Yeah, very funny, especially since they don't have any other pragmatic reasons
to use it, ie. it being a more dynamic OO C than C++ while retaining full C
power, them having huge API libraries for it over 25 years of NeXT/OS X
development, etc etc.

> _Prefixes are not a solution as they have no ways to avoid collisions._

It's not like you use lots of third party libs (if any at all) in OS X.

> _So much for supporting large scale development with Objective-C._

Yeah, I mean they have just those tiny projects in it, like iPhoto, Final Cut
Pro, Pages, Numbers, the whole Cocoa and Cocoa Touch stack, etc.

But we need more support for large scale development, because there are many
many teams of 100s of programmers that also want to write 20 million lines
Objective-C programs.

And C is even worse, you just have small projects like the Linux kernel
written in it, due to the severe issue of lack of namespaces.

/s

~~~
pjmlp
> It's not like you use lots of third party libs (if any at all) in OS X.

Yeah, that only works if you don't use any third party stuff.

> Yeah, I mean they have just those tiny projects in it, like iPhoto, Final
> Cut Pro, Pages, Numbers, the whole Cocoa and Cocoa Touch stack, etc.

There are all internal Apple projects, as such the company can decide which
prefixes to use. If they happen to clash with some third party small company,
bad luck for the external company.

> But we need more support for large scale development, because there are many
> many teams of 100s of programmers that also want to write 20 million lines
> Objective-C programs.

Well, most projects I work on professionally, are the typical enterprise
projects with 100+ developers, scattered across the globe.

> And C is even worse, you just have small projects like the Linux kernel
> written in it, due to the severe issue of lack of namespaces.

While you're being sarcastic here, let me tell you that Linux kernel works,
because everyone that wants to add code to the kernel is obliged to follow
certain conventions.

You cannot have that with third party code that you don't control.

Specially if it is delivered as commercial closed source libraries, which is
quite common in the enterprise world.

------
astrange
Despite the accepted answer saying to use bundle unloading, please don't. It
may be supported in theory but in practice unloading a bundle leaves all kinds
of opportunities for stale pointers and crashing.

------
SoftwareMaven
As much flak as Java gets, at least they got namespaces right. Python got
better, but it's still not what I would call great.

~~~
fleitz
At first glance yes, but as always with Java when you dig under the hood you
see tight coupling to bad ideas from the early 90s. Given the OO/Java mantra
of decoupling I'm not sure why the namespace is a consequence of the filepath
they seem far too tightly integrated.

~~~
eropple
Agreed - C# fixed this, though (by default it maps to the directory structure,
but you can change this). Scala encourages Java-style packages but lets you
put them wherever you want.

~~~
lmm
I find that an irritating pain with scala, actually. I move a file from one
directory to another, then spend ten minutes trying to figure out why lift
still can't find the class, before the facepalm moment where I realise I
didn't change the package declaration _in_ the file.

~~~
eropple
I agree that it's actually sort of stupid to allow it--I used the word choice
I did intentionally, because C# 'fixed' it (its strong IDE support makes
having files in different places pretty much impossible unless you want it to
happen), but Scala isn't so lucky. At least I get it when I use IntelliJ,
which doesn't even tell me before updating the package declaration. :)

I use Play or a home-rolled solution based on vertx, though. so I don't have
to worry so much about finding them.

~~~
lmm
I hate magic package names; I'd far rather be using wicket, but I wanted good
comet integration for this particular project.

