Class is implemented in both. One of the two will be used

57,589

Solution 1

I wrote that error message!•

Either change the class name or don't link against said library.

How is your project configured? Is there anywhere where you explicitly link against SR? Or is it a product of linking against two static libraries that both already include SR?

If the former, then stop linking against SR directly and just inherit the version that came with the library already using it (warning: make sure it has the right version).

If the latter, then you are going to have to modify one of the libraries.

• Actually, I modified the error. It used to imply that one or the other would be used. But that wasn't really what was going on and the behavior was different across different platforms. Thus, it was changed so that it was far more precise in identifying that the behavior was undefined.

Solution 2

In my case this error appeared when I unnecessarily added a source file to both my main app target and my test target:

Target Membership with both targets selected

Removing the test target from Target Membership solved it:

Target Membership with only one target selected

Solution 3

Overview:

The error suggests that the same symbol / class is defined twice.

Solution:

  • Check the frameworks linked to see if there are any duplicates. If so remove the duplicate
  • Clean build folder (Command + Shift + K)
  • If simulator, then reset the simulator and try
  • If device, restart the device and try

My experience:

I faced the same issue twice, once it was duplicate frameworks and the other time resetting simulator helped.

Solution 4

I had this warning for more than a month, then I finally tried this and it worked for me:

  1. Reset the simulator (Menu: Hardware -> Erase all content and settings ... )
  2. Clean the project (Command + Shift + K)
  3. Clean the build folder (Command + Option + Shift + K)
  4. Run the code on the simulator again
Share:
57,589
MrGrinst
Author by

MrGrinst

Updated on July 09, 2022

Comments

  • MrGrinst
    MrGrinst almost 2 years

    I have a project that has a dependency (installed via CocoaPods) using SocketRocket and have imported a static library from HeapAnalytics. Apparently the HeapAnalytics library already uses SocketRocket. I get no errors when compiling, but at runtime receive the following:

    Class SRWebSocket is implemented in both [path] and [path].
    One of the two will be used. Which one is undefined.
    

    I'm not sure how to handle it because most solutions I've seen require compiling the static library yourself change class names and such, and I don't have access to the source.

    Any recommendations?

  • MrGrinst
    MrGrinst almost 9 years
    Thanks bbum. Unfortunately, this confirms my suspicions that I'm going to have to completely modify one of the libraries.
  • MrGrinst
    MrGrinst almost 9 years
    Well the fix was a lot easier than I thought. I guess I thought I needed to do something really complicated but all I had to do was refactor -> rename all occurrences of SRWebSocket and it's accompanying inner classes. The only trouble I can foresee with doing this is that if the non-HeapAnalytics libraries are using a different version of SR, there could be some issues.
  • bbum
    bbum almost 9 years
    @MrGrinst Excellent! Yeah-- there really isn't a notion of namespaces in ObjC and, thus, collisions like this are problematic.
  • Amin Negm-Awad
    Amin Negm-Awad almost 9 years
    How could namespaces help? It still would be SR:… and SR:…!?
  • bbum
    bbum almost 9 years
    @AminNegm-Awad Effectively, link time namespaces. That is, static library A would link the SR library and the symbols wouldn't be exposed beyond that library. B could do the same with a different copy. In practice, it causes as many problems as it solves.
  • Michael A
    Michael A almost 9 years
    @bbum how can a project use framework classes which are in another framework that the project is linking? (like you say in your answer this apply to the first situation where project explicitly link against SR) if i dont put the import<framework_name> it wont recognize the framework classes
  • Lena Bru
    Lena Bru over 8 years
    is there a way to silence this warning?
  • Admin
    Admin almost 8 years
    @bbum is there something that can be passed to dyld, maybe via some DYLD env var to let it just pick one?
  • bbum
    bbum almost 8 years
    @EdgarAroutiounian Nope; it is non-deterministic. The warning can't be silenced as it is, effectively, a ticking time bomb in a project. (Technically, it is deterministic, but it changes behavior across platforms and releases).
  • Admin
    Admin almost 8 years
    @bbum thank you, any way to give a collection of dylibs and sanity check them before hand if duplicated symbols among collection, sans writing custom code.
  • quarac
    quarac over 7 years
    @bbum Thanks for your hard work, I have a question about this: will be a problem if importing two different external libraries that contains a class with the same name?
  • bbum
    bbum over 7 years
    @quarac yes. Same problem. One class will win.
  • Raphael
    Raphael about 6 years
    In a world where I configure my dependencies using CocoaPods, and my dependencies depend on I don't know what at whichever version they please, how do you propose to avoid this scenario? Imho, the tooling should take care of this -- either CocoaPods should detect duplicate dependencies and handle them correctly (in my case, it duplicates the exact same version of a framework), and/or the Swift build chain needs to disambiguate correctly.
  • bbum
    bbum about 6 years
    @Raphael The only correct disambiguation is to not allow two classes of the same name to be in the link simultaneously. Without a hardline guarantee of instances of Class A never escaping the innards of a particular module, there is no way that a different class named A can co-exist in the runtime. Keep in mind that allow co-existance of different implementations of the same named class breaks a number of fundamental principals of Objective-C (and Swift).
  • Raphael
    Raphael about 6 years
    @bbum I agree that we can't have duplicates in the build artifact. I'm saying the tools should prevent that from ever happening.
  • bbum
    bbum about 6 years
    @Raphael How? By definition, Objective-C allows the lookup of un-aliased class names. If you have a class named "BobsYourUncle", that name cannot be mangled and must be able to be universally looked up or you break a fundamental premise of Objective-C. So, the tools are preventing it by warning you that a problem exists.
  • Raphael
    Raphael about 6 years
    Speaking in complete ignorance of the details of Objective-C and the Swift compiler, if I use the/a standard dependency manager and build tool chain (CocoaPods, XCode, xcrun) and get such errors/warnings, something is broken. I don't know if it's the concept, the dependency manager, the compiler, the runtime, or a combination of them. And I don't care. Those are things that, in 2018, I expect tools to handle for me. If they don't, I'll use something else. Shifting the work onto the user is not a practicable solution here. </opinion>
  • bbum
    bbum about 6 years
    @Raphael fix the ignorance and you’ll understand why it cannot be fixed without changing a fundamental design point of objc. What you are claiming is akin to claiming that “the fragile base class problem is ridiculous in 2018”. Every language or tool makes tradeoffs to solve a set of problems. Those tradeoffs include adopting other problems as a necessary part of the system. Objective-C embraces at runtime meta programming capabilities at the cost of no namespaces or other module divisions.
  • Mark A. Donohoe
    Mark A. Donohoe almost 6 years
    My issue is I'm trying to launch Messages from the terminal, so not my app. Here's what I get... Class IMEmoteMessageChatItem is implemented in both /System/Library/PrivateFrameworks/IMCore.framework/Versions/‌​A/IMCore (0x7fffdf806d48) and /Applications/Messages.app/Contents/MacOS/./Messages (0x102641a80). One of the two will be used. Which one is undefined. Illegal instruction: 4. So how can I launch this if I don't have control over the app or code?
  • Mark A. Donohoe
    Mark A. Donohoe almost 6 years
    All I'm executing is ./Messages from within the MacOS folder in the Messages.app bundle.
  • drew..
    drew.. over 5 years
    In my case, the above, less the reset. A simple cmd-K on the simulator was sufficient (as i had a few other dev apps that had setups I did not want to lose).
  • totiDev
    totiDev about 4 years
    In my case it was under Dependencies that I had the duplicate, which then fixed the issue for me.