8

Is there a way to refactor mixed C++/Objective-C code in Xcode ?? I am writing a game using Cocos2D and Box2D, and the Box2D is written on C++, so every class I write should have .mm extension and therefore when I try to e.g. rename the variable, I got a message like "Xcode can only refactor C and Objective-C code".

Thanks in advance!

NSGod
  • 22,699
  • 3
  • 58
  • 66
Terko
  • 155
  • 1
  • 1
  • 5
  • 2
    it's "refactor" not "refractor" - that would be a telescope ;) – CodeSmile Apr 05 '13 at 20:11
  • 1
    for refactoring i *sometimes* use appcode, its refactoring is more powerful. However it's slow to load so for me it's still more practical to rename in xcode. – CodeSmile Apr 05 '13 at 20:13

4 Answers4

10

Xcode is VERY limited with refactoring, even with plain Obj-C. It's basically renaming and it can't even rename in comments. If it says it can't do something, then it probably can't.

The only way to rename is using find & replace. Note that Xcode can handle regular expressions so it is often good enough.

Of course, the problem is that find & replace doesn't know the programming language and sometimes can add some extra replace or forget to replace something, therefore be extra careful. Clean build is neccessary after every refactoring to check everything got renamed correctly.

You can also use command line tools (e.g. sed) to achieve the same.

NSGod
  • 22,699
  • 3
  • 58
  • 66
Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • Thank you! I just wanted to know the way people usually cope with it when working on big projects. Do they use find & replace tool too? – Terko Apr 05 '13 at 18:07
  • 1
    @Terko Hard to say. I guess everybody is a bit different. Also note that XCode is not the only IDE on the market. It's the default and it's free but it's not the only one. I heard very good references for [JetBrains](http://www.jetbrains.com/objc/), which has "Reliable refactorings" as one of its major features. I don't know whether it can refactor Obj-C++ or not but it's probably much better IDE than XCode. – Sulthan Apr 05 '13 at 19:35
  • @Sulthan - in many respects it is vastly superior , in others not (see Stefen's remark above). I now use xCode strictly for (rare) project setup activities, (always) organizer activities, and (never) code, test and integration. If they can resolve the performance issues and add the missing functions, xCode will soon be ExCode for me. – YvesLeBorg Apr 06 '13 at 12:17
  • 1
    @Sulthan - mind that Refactoring isn't simply renaming things.. Most of the time I use refactoring features of modern IDEs to extract methods, change signatures or move stuff between classes/namespaces. – Jay Jun 28 '13 at 18:47
  • @Jay You are unfortunate because Xcode is not a modern IDE. It cannot do advanced stuff. – Sulthan Jun 29 '13 at 01:31
  • 1
    1.5 years on **AppCode** got pretty stable (Still the occasional refactoring bug) so that's what we use now for refactoring.. – cacau Jan 19 '15 at 07:17
3

I had the same problem in the cocos2d/box2d game I am building.

Fact 1: Xcode 4 can refactor C and Objective-C (.m files) code but it cannot refactor Objective-C++ code (.mm files).

Fact 2: If you want to interact with box2d (which is written in c++) you need to use Objective-C++.

I have (partially) addressed the problem following these steps:

  1. I created a few wrappers in Objective-C++ for the box2d classes I needed to interact with (e.g. MyWorld.mm is a wrapper of the c++ class b2World and MyBody.mm is a wrapper for the c++ class b2Body). Here it is crucial to avoid any reference to box2d in the .h of the wrappers.
  2. In every other class of my project I never referred directly the box2d classes, I referred instead the related wrappers. Of course I also removed #import "Box2D.h" from these classes.
  3. I converted to plain Objective-C (.m) every other class of my project.

The result is that now Xcode can refactor every class of my project but the wrappers of course.

P.S. Of course when you need to use a wrapper (e.g. MyWorld) in you Objective-C classes you must import MyWorld.h and not MyWorld.mm.

Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148
2

You might want to check out this project on github - it's a work in progress, but still:

https://github.com/lukhnos/refactorial

It's a c++ refactoring tool based on Clang (i.e. the compiler Xcode itself is based on).

cacau
  • 3,606
  • 3
  • 21
  • 42
0

I had some kind of a solution - to separate Objective-C and Objective-C++ code. There are some macros which allow to detect if the file used in pure Objective-C. Example:

http://philjordan.eu/article/strategies-for-using-c++-in-objective-c-projects

The idea is you still can't refactor .mm files but you can refactor all the other code even if it includes Objective-C++ code.

Vyachaslav Gerchicov
  • 2,317
  • 3
  • 23
  • 49