Redefinition of as a different kind of symbol in Objective-C - objective-c

We have a class WayPoint. But at some point, we decided to rename the class to Placemark. However, we don't really want to change the name of the class because it will result in a lot of modification of the existing code. Therefore, I added one line of typedef at the bottom of the header file and start using Placemark in any new code happily ever since.
#interface WayPoint : _WayPoint
#end
typedef WayPoint Placemark;
But there is still one thing that I don't understand. If I try to use the forward definition in some other header file. I can only used:
#class WayPoint;
If I use:
#class Placemark;
I will get the error message:
Redefinition of 'Placemark' as a different kind of symbol
Why?

Not sure why can't you use Xcode's refactoring features (Simple Rename does it fast and easy). But if you really want to do this you may use something better then typedef:
#compatibility_alias Placemark WayPoint

Because typedef Placemark is an alias and you are trying to use it as a class
symbol.
So error clearly indicates
Redefinition of 'Placemark' as a different kind of symbol
which means your class name and typedef alias are different symbol.

Related

Weird syntax errors in header file

I have a header file containing an interface with properties and methods (let's call it E.h), and Xcode notifies me about syntax errors inside this header field, which make no sense because E.h doesn't contain any error.
These errors appear only under certain conditions:
E.h is already included in A.h, and there is no error.
When E.h is not included in B.m, there is no errors and it compiles fine, but if I include it in B.m, errors show up. (B.m doen't use any code from E.h)
Additional information: B.m includes B.h and then E.h .
I didn't find relevant to include source code because it represents thousands of lines and I won't ask you to analyze this.
I jus need some hints for what could be the cause and where to start searching.
Thanks in advance.
By using the "Show Preprocess" option in Xcode, I found that the property in E.h named #property (retain) NSString *MY_STRING; was replaced with #property (retain) NSString *#"My String". It appeared that there was a define MY_STRING #"My String" included in a different header file itself included in B.h, itself included in B.m before E.h .Hard to spot ! Lesson of the day : never write your variables in upper case.
In C++ this works, maybe will help you:
in file E.h
#ifndef __ECLASS__
#define __ECLASS__
<here original declarations from E.h>
#endif

I am having all the time this issue after running my app

I don't know why, but after a while working without problems I added some buttons, then I launched my app and this error appeared:
ld: duplicate symbol _x in
/Users/alexbarco/Library/Developer/Xcode/DerivedData/RecolectaDatos-ayjpqqcajbhuzvbkvernzsyunpbe/Build/Intermediates/RecolectaDatos.build/Debug-iphonesimulator/RecolectaDatos.build/Objects-normal/i386/SeconViewController.o
and
/Users/alexbarco/Library/Developer/Xcode/DerivedData/RecolectaDatos-ayjpqqcajbhuzvbkvernzsyunpbe/Build/Intermediates/RecolectaDatos.build/Debug-iphonesimulator/RecolectaDatos.build/Objects-normal/i386/ViewController.o
for architecture i386 clang: error: linker command failed with exit
code 1 (use -v to see invocation)
Whenever I have duplicate symbol errors, it is almost always because I have a circular #import in my headers. The solution is quite simple, use forward declarations where possible, and #import .h files from .m files instead.
There are just two cases where you need to #import one .h from another:
if you are extending the class in the #import
you are implementing a protocol in the #import
Specifically, you do not need to import files just to use a class name or protocol in your signatures; instead use forward declarations.
For example, this (in Bar.h):
#import "Foo.h"
might become this (Bar.h):
#class Foo;
#protocol FooDelegate;
and bar.m:
#import "Foo.h"
Here is a link to the documentation on forward declarations.
The "duplicate symbol" message means that you're declaring some name (in this case, _x) twice in the same scope. Say you had code like this:
int _x = 1;
int _x = 2;
You'd expect to get an error then, right? You can use the same name for two things at the same time.
The error you're getting is essentially the same. You're declaring _x somewhere, and from the compiler's point of view you're doing it twice. There are a few ways to deal with this, depending on what _x represents.
chrahey's answer explains about forward class declarations. I won't cover that again here except to say that a forward declaration helps you resolve circular references, where the definition of class A depends on class B and vice versa.
If _x is a variable, it's likely that you're trying to declare it in a header file. The compiler basically copies the contents of each header file that you import into the source file, so if you declare a variable in a header file and then import that header into two or more implementation files, you'll end up with multiple declarations of that variable. To get around that, use the extern keyword to tell the compiler "this name will be declared somewhere else" and then put the real declaration in an implementation file:
Foo.h:
extern int _x;
Foo.m
int _x;
Pretty much the same thing goes for functions. It doesn't appear that _x is a function, but if it were, and if you were silly enough to put the function definition in a header file, then you'd again get an error if that file were imported into more than one implementation file. This is why header files contain prototypes, not definitions:
Foo.h:
int foo(int a);
Foo.m
int foo(int a)
{
return a + 10;
}

Any way to replace part of word with the preprocessor?

I have something like this in my objective-C class
#interface PREFIX_MyClass {
...
#end
and I'd like to use the preprocessor to convert it to:
#interface AwesomeMyClass {
...
#end
so something like
#define PREFIX_ Awesome
doesn't work because it's a part of a word. Any other way? I know I can use something like this:
#define PrefixClass(NAME) Awesome##NAME
#interface PrefixClass(MyClass)
but I don't like this because it breaks code complete and reference following in dev tools (i.e.: Xcode in this case)
This isn't very elegant, but you could use the preprocessor to replace the entire class name instead of just part.
#define PREFIX_MyClass AwesomeMyClass
#interface PREFIX_MyClass
Of course, this becomes an issue if you use the prefix more than once and it changes. You could fix this using by using another calling another macro to add the prefix, so that only one macro contains the actual prefix.
#define ADD_PREFIX(name) Awesome##name
#define PREFIX_MyClass ADD_PREFIX(MyClass)
#interface PREFIX_MyClass
This still requires a macro for everything you want to prefix, but code completion will recognize the PREFIX_MyClass name.
This is not exactly what you're asking for, but it may be another route to accomplish your goal. Xcode allows you to define a class prefix for your project. Select your project in the file navigator, and in the file inspector (first "tab" of the right sidebar) you will have this:
Whatever text you put into the "Class Prefix" field will be prepended to the names of any classes you create in that project.

Call Static Method with C Syntax in Obj-C?

I could redo this method using proper Obj-C syntax, but I was wondering how to call this from Obj-C. The method looks like this
#interface YarMidiCommon : NSObject
static
MIDIPacketList *makePacketList(Byte *packetBuffer, const UInt8 *data, UInt32 size);
#end
but I have no idea how to call that method. I have tried
Byte packetBuffer[size+100];
MIDIPacketList *packetList = makePacketList(packetBuffer, bytes, size);
but the error is "has internal linkage but is not defined." Is this possible without resorting to "proper" Obj-C syntax?
For the record, the method that I want to emulate would be something like
+ (MIDIPacketList*) makePacketListWithPacketBuffer:(Byte*)packetBuffer data:(const UInt8 *)data size:(UInt32)size;
which is verbose and annoying, seeing as everything here is C anyway.
This is related to this other answer I got today.
Since the function is a C function you need to remove the static keyword or else it will not be visible outside of its translation unit. Once you do that the first example you have will work. Also since it is a C function placing its declaration inside or outside of the #interface and definition inside or outside of the #implementation makes no difference on how you will call it.
Consider the declaration as being equivalent to static C function in the global scope. This is much unlike C++ or Java. There is no class scope or external linkage for this function.
As such, the #interface scope would not be a good place to declare makePacketList. The message means the definition is not visible when you use it.
You need to move the function to the .m (makes sense if you use it from this file only) or remove the static keyword.

Where to declare an enum struct?

This is just out of curiosity but when i declare an enum type, would it be better to have it within an implementation declaration or outside of it? What would be best practice? For example:
#implementation PostQuestionScene
enum popUpItems{
kExpiredBox,
kPauseBackground
};
vs..
enum popUpItems{
kExpiredBox,
};
#implementation PostQuestionScene ..
I tend to always have a typedef so it's just like another variable:
typedef enum {
kExpiredBox,
kPauseBackground
} popUpItems_t;
Then create instances of it.
popUpItems_t popUpItems;
If you will use it outside that module, put the typedef in the header so when the header is included, other modules have the typedef at their disposal (if they need to take it as an argument, for example,) otherwise put it in the implementation (think public/private variables.)
I don't think it makes any technical difference. I would place it before the #implementation (along with all other miscellaneous declarations) unless it is just used in one or a small group of methods, in which case I would place it immediately before those methods.
Of course, if it might be used by clients or subclasses it should be in your header file (where #interface is) so that the definition is visible to them.