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

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;
}

Related

Equivalent of public static final variables

I understand that placing the word extern before a variable declaration in a header file declares the existence of a global static variable without initialising it. I also understand that if I import the file containing the extern variables, I can reference them without a class/file name. But where does one define them and their values?
What I am trying to do is create a class of constants with global constants that I want to use throughout an iOS application's code.
Does one put them inside the interface like this?
Example.h
#import <Foundation/Foundation.h>
#interface Constraints : NSObject
{
extern NSString * const PREFS_NAME;
}
Or does one put then outside of the interface like this
Example.h
#import <Foundation/Foundation.h>
extern NSString * const PREFS_NAME;
#interface Constraints : NSObject
{
}
Then in the implementation .m file how would one initialise the extern values?
Inside the implementation area like this?
Example.m
#import "Constraints.h"
#implementation Constraints
/**PRefecences name for the application**/
const NSString * PREFS_NAME = #"MyApp_Prefs";
#end
Or do initialise them outside of the implementation area like this:
Example.m
#import "Constraints.h"
/**PRefecences name for the application**/
const NSString * PREFS_NAME = #"MyApp_Prefs";
#implementation Constraints
#end
Or do I provide them their initial values in a constructor? or some arbitrary a static style method with + in front of it i.e. +(void) setAppConstraints;
I have tried several combinations, but always run into errors, such as "Redefinition of 'xVariable' with a different type". Or a something about "extern does not have an initialise interface" (or something like that, I forget). So I want to know how to declaire and initialise them properly to form the same role as public static final variables in Java.
Also what are the limits of the extern command? I know I can extern an NSInteger or NSString, but what about NSArray?
I am asking this question because there seems to be to much misleading, or incomplete, information regarding the use of extern in Objective-C. Many of the answers seem speculatory. My hope is for this question to be a good resource not only for me, but to limit further similar questions about the basics of extern.
You define it's value in the file inside which it's declared, which in your case is Example.m; You can still re-assign this variable, so the declaration in Example.h would look like this:
extern NSString * PREFS_NAME;
This way every file that imports Example.h has access to this variable. The equivalent of public static final in Objective-C is const. If you also want it to be public you should make it be a class instance variable, but in this case you don't need it because it's already accessible everywhere. So in this case it would be:
// .m file
NSString* const PREFS_NAME = #"MyApp_Prefs";
// .h file
extern NSString* const PREFS_NAME;
Also notice that const NSString* is different from NSString* const. The latter is a const pointer to NSString. The former hasn't sense even if it's a correct syntax. In Objective-C the const qualifier doesn't affect objects, instead there are mutable and immutable classes. It would have sense in C++ meaning that you can use just const methods on the instance.
extern is used to signal the compiler that you will be using a variable or a function that is defined in another compilation unit.
When you say extern const NSString *PREFS_NAME, you're saying "Replace all references in this compilation unit to PREFS_NAME to the variable PREFS_NAME as it is defined in another file." So when you try to assign PREFS_NAME in your .m, all you're doing is trying to assign a variable that, though it has a name, it doesn't exist. Declaring a variable extern is only a declaration of a variable or function, not a definition of that variable or function. It lets the compiler know that the name is in use, and that the linker will take care of what to do with it, but even if you provide a type here, it doesn't actually set aside space for the variable, it's expecting the space to be set aside in the compilation unit that's actually defining the variable.
You compile three or four different source code files together, three of them may declare:
extern int buffer[];
And one may declare
int buffer[BUFSIZE];
In its global scope, and the linker's job is to resolve the three declared references to extern buffer to the fourth's actual definition of the buffer.
extern is to C variables and functions much as #class is to Objective-C classes, it's a forward declaration, a promise to the compiler that you don't have to freak out when you see a name that's undefined here, because the linker will answer whatever lingering questions you may have.

objective c - static variables puzzling behavior

In an .h file I have the following line (outside of any #interface block):
static NSMutableDictionary *dictLookup;
In the corresponding .m file I try to initialize that static in the init method of the class:
dictLookup = [NSMutableDictionary dictionary];
dictLookup setValue:#"Hello?" forKey:#"Goodbye"];
However, when I insert breakpoints and do checks, dictLookup never becomes anything other than nil.
Also, I get a bizarre warning "Unused variable dictLookup" at compile time. Bizarre because if I delete the static declaration, then I get an "Undeclared identifier" compiler error at the lines in the init method.
I've since discovered there are better ways of doing what I want. But what was going on here? (1) Why can't I set dictLookup to anything?
Some sources seem to say that in C a static variable can only be used in the file in which it is declared. (2) If so, then why doesn't compiler fail with an error in the .m file? Given (1) that would seem to be the logical thing to design the compiler to do.
And (3) When I designed a new 'test' project from scratch, with a new .h/.m file combo like the one described, I WAS able to set dictLookup and insert keys. Why could accoutn for this difference?
When you put a declaration of a static variable in a .h file, it gets re-defined in every .m file from which the header is included. A brand-new variable will be created in each file, with the same name.
This is not an error in the .m file: the variable is local to that file, and invisible to the linker, so there are no "multiple definitions" error.
That's because your test project used a single .m file.
Some sources seem to say that in C a static variable can only be used in the file in which it is declared.
That is absolutely correct: a static variable is very much like a file-scoped global variable, it should be defined in the .m file. If you want to share a variable, it needs to be a global then. Declare it in the header with the extern keyword, like this
extern NSMutableDictionary *dictLookup;
and then define it in one of the .m files like this:
NSMutableDictionary *dictLookup;

Add constants issues Xcode 4.5

I've got a class for storing constants.
So, there are two files that call Constant.h and Constant.m
This is what I have in .h file:
#import <Foundation/Foundation.h>
enum kParams {
kFirstName = 0,
kLastName = 1
};
extern NSString * const kNotificationUpdateMainMenu;
This is what I have in .m file:
#import "Constants.h"
NSString * const kNotificationUpdateMainMenu = #"kNotificationUpdateMainMenu";
For first time it works good, but when I try to add some other const (kNotificationFbLoginSuccsess for example) other classes don't see it.
This is a message that shows me which problem I have. But I don't understand how my other constants work without this issue (just new constant that I add get this error).
/Users/developer/Documents/Projects/Test/Test/Test/AppDelegate.m:121:64: Use of undeclared identifier 'kNotificationFbLoginSuccsess'
I found some way how to fix it:
Open organizer
Clear derived data
Delete project.xcworkspace file and xcuserdata
Close Project
Relaunch Xcode
but as I think is too much operations that I can add one constant. How come?
Your "global" constant is not actually external (separately compiled and later linked together). Take the easy way out and place NSString * const kNotificationUpdateMainMenu = #"kNotificationUpdateMainMenu"; into the header file. The method file needs nothing.
I would use #define kNotificationUpdateMainMenu #"kNotificationUpdateMainMenu" to perform the spell checking. The compiler will create one shared instance of the constant string for the entire compilation.

Declaring variable above vs below #interface

int helloness;
#interface test : NSObject
#end
vs
#interface test : NSObject{
int helloness;
}
#end
Do I understand that following are true and the only meaningful differences between the above two blocks:
in both blocks, the implementation of test.m can use helloness variable internally, like an ivar
in the first block, helloness will exist for any class that imports this .h but is otherwise private only to test.m in the second block
In the first block, is this technically what is considered a "global variable" in that any class that imports this will have access to the same contents of helloness?
What happens if multiple header files have a declaration for helloness and you import them all?
Similar to this, consider this implementation:
#implementation AClass
int food=5;
Here, food acts like an internal iVar, even though it was not declared in any #interface ?
In your first example, helloness is a global variable. It can be seen by any file which imports that header. If you include multiple headers which also declare an int helloness variable, I believe you'll get a warning from the compiler, and all of them will point at the same memory location. If you include another header which declares a helloness of type other than int, I believe you'll get a compiler error.
In the second example, helloness is an instance variable (ivar). Its value (memory location) is specific to each instance of AClass. (Anything can access it: e.g. AClass *instance = [[AClass alloc] init]; instance->helloness = 7; However, direct access to ivars is generally avoided in ObjC -- we use accessors and/or properties instead.)
In the third case, food is still a global variable, but its visibility is restricted to the implementation file it's declared in. Any instance of AClass, as well as any other classes or categories or functions implemented in the same file, can reference food, and all those references are to the same memory location.
In your first example, helloness is a global variable. In your second example, it's an instance variable.
There can be only one global variable with a given name in your program. There is a copy of an instance variable for each instance of your class that's created during your program's execution. They're not semantically similar at all.
Having a global variable in a header file, as I presume you are doing in the first example since you refer to #importing it, is probably a bad idea. If it's not a tentative definition like yours is (for example if you instead had int helloness = 12;), you'll end up with multiply defined symbol errors at link time.
In your last example, food is still a global variable, but since it's likely to be in an implementation file (rather than a header), you probably won't run into any multiply defined symbol errors. It won't work like an instance variable, though - it's still a global variable.

C Header Files - Good Practice

I am used to Objective C header files and am not sure how C header files are used in terms of good practice.
Where would one #include other source files, in the header file or the .c file?
Does the same idea apply to C where .c files include their own header files. and other files include the .h files of the source they want to include?
Is there anything equivalent to the #class usage in Objective-C?
Is it good practice to declare pointers in the .h file and initialize them/alloc them in the .c file?
You normally distinguish between source and header files in the same way that Objective-C differentiates between implementation (.m) and interface (.h) files. Source files contain everything that may execute, header files contain enough information about symbols that other source files know how to communicate with that source file.
Header files often include other header files, so you'll see #include in both source and implementation files. #include operates exactly like #import except that it doesn't automatically check whether you've #included the same file twice. So C header files often look something like:
#ifndef __SOME_SYMBOL
#define __SOME_SYMBOL
... rest of header file here ...
#endif
Which has the same effect of ensuring the main body of the header file is included only once.
EDIT: more on this, as per request. Obviously you'd never do something like:
#include "File.h"
#include "File.h"
But you can easily end up with something like:
#include "FirstComplexThing.h"
#include "SecondComplexThing.h"
Where both FirstComplexThing.h and SecondComplexThing.h rely on something inside and hence #include SimpleThing.h. So you end up with SimpleThing.h #included twice, without making any sort of error or following any bad design pattern.
C compilers work just like Objective-C compilers — each source file is compiled on its own, in isolation, with no overview until the linker comes along. #include is a preprocessor directive that has the same logical effect as copying the contents of the named file and pasting them into your source file at that location, so if you end up the same file #included twice you'll probably end up with something like:
char *somePointer; // I'm from SimpleThing.h
... lots of other things ...
char *somePointer; // I'm from SimpleThing.h
And the compiler will stop with an error that the same thing is declared twice. #import in Objective-C avoids that by being shorthand for '#include, but only if you haven't already #included that file'. The C #ifndef/#define/#endif convention achieves the same thing as #import because the #ifndef/#endif pair say that the stuff in between should be passed on to the compiler if the nominated preprocessor symbol (__SOME_SYMBOL in my example; it tends to be a name derived from the name of that header file but exact conventions vary) hasn't been defined. It won't have been the first time the construct is encountered. Because it is defined inside the construct, it will have been when the same #ifndef is encountered the second time, so the stuff up to the matching #endif won't be passed on.
Although it's a question of style, it is very often the case that each C file has one H file that is directly connected to it.
There are no classes in C, obviously, but if you mean a construct like:
#class SomeClass;
#interface SomeOtherClass: NSObject
{
SomeClass *otherClass; // I can reference SomeClass without importing
// the interface file because I've declared the
// type above
}
- (void)whatever;
#end
That's actually the normal C distinction between declarations and definitions. You'll have a problem if you do something like:
struct SomeStruct;
struct SomeOtherStruct
{
struct SomeStruct otherStruct;
};
Because the compiler doesn't have enough information. It doesn't know how large SomeStruct should be, so it can't work out how SomeOtherStruct should be laid out. However, this is completely valid:
struct SomeStruct;
struct SomeOtherStruct
{
struct SomeStruct *otherStruct;
};
Because the size of a pointer is always known, irrespective of what it is pointing to. You'll often see that C libraries with opaque types describe those types by pointer only (sometimes to void *, but not always — e.g. stdio.h uses FILE *) or just give you an integer (including OpenGL, notably). So they ensure you've something that the compiler will know the size of without having to tell you what data they're associating with it or giving you any way to try to manipulate it yourself.
It's perfectly good practice to put pointers in the header file (assuming it's good practice to expose the thing globally, obviously). The same thing is often done in Objective-C, albeit for slightly different reasons, e.g.
// interface/header file
extern NSString *someGlobalIdentifier;
And:
// implementation/source file
NSString *someGlobalIdentifier = #"somethingOrOther";
In Objective-C that's because you can then test identity rather than always having to test equality, but basically the same rules apply to C with respect to it being normal to put the reference (be it a pointer or whatever) that represents a thing into the header and create or declare the thing in a source file. In fact, if you start putting declarations in the header file you'll end up with errors when the program comes to link because multiple source files will think they declare the thing.
->#include is working in c and objective c.
->But generally in objective c, always used #import.
->#include and #import are different, when you used #include compiler generate one separate copy of .h file, and if you used #import then compiler generate only one copy at a time
Is there anything equivalent to the #class usage in Objective-C?
-> No there is no any other equivalent
Is it good practice to declare pointers in the .h file and initialize them/alloc them in the .c file?
-> Yes if your object is public, then you must declare in .h file, but always is good practice that initialize them it in constructor.
This is how I finally figured out how to do this properly. After long time of trying and failing at what used to be a simple thing.
//this is the mechanics.h file
#ifndef ProjectA_mechanics_h
#define ProjectA_mechanics_h
#ifdef __cplusplus
extern "C" {
#endif
int funcAdd (int A, int B);
#ifdef __cplusplus
}
#endif
#endif
// this is the mechanics.c file
#include "mechanics.h"
#include <math.h>
int funcAdd (int A, int B)
{
return A + B;
}
math.h is there "just because"
have fun, dang this sucked for while