How do I properly declare a global variable in a header file? - objective-c

I was testing some code where I declare a global variable in a header file, but I'm getting a linker error: "duplicate symbol"
header file:
//
// GlobalVaraibleClass.h
// GlobalVar
//
#import <Foundation/Foundation.h>
int gGlobalVar = 0;
#interface GlobalVaraibleClass : NSObject
#end
class file:
//
// GlobalVaraibleClass.m
// GlobalVar
//
#import "GlobalVaraibleClass.h"
#implementation GlobalVaraibleClass
#end
main:
//
// main.m
// GlobalVar
//
#import <Foundation/Foundation.h>
#import "GlobalVaraibleClass.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
extern int gGlobalVar;
NSLog(#"Hello, World! %i", gGlobalVar);
}
return 0;
}
where am I going wrong?

That is backwards, the extern goes in the header, the declaration setting the value goes in the implementation file.
The extern specifies that the variable will be declared somewhere else. If the declaration is in the header every time the header is included there will be another declaration and at link time there will be multiple definitions which will not link.
Example:
// GlobalVaraibleClass.h
extern int gGlobalVar;
// GlobalVaraible.m
#import "GlobalVaraibleClass.h"
int gGlobalVar = 3;
// main.m
#import <Foundation/Foundation.h>
#import "GlobalVaraibleClass.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSLog(#"Hello, World! %i", gGlobalVar);
}
return 0;
}

Related

Newbie Objective C Error such as _main

I've been tinkering all day, and I can't seem to fix this error.
Here's the code:
//
// main.m
// Learning ObjC
//
// Created by Nickirv on 8/9/15.
// Copyright (c) 2015 Nickirv. All rights reserved.
//
#import <Foundation/Foundation.h>
#interface Person: NSObject{
int age;
int weight;
}
-(void) print;
-(void) setAge: (int) a;
-(void) SetWeight: (int) w;
#end
And it outputs this issue:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I would appreciate any help! Thank you very much!
You can't delete the main boilerplate code:
int main(int argc, const char * argv[]) {
#autoreleasepool {
}
return 0;
}
In the end Objective-C is "C" and the program starts execution by calling main. Additionally Objective-C code needs to execute in an autoreleasepool.
You define class #interfaces and #implemtations outside of (generally above) the boilerplate but the first line of code to run must be within the autoreleasepool scope {}.
Here is an example Objective-C program similar to what the OP seems to want using #properties for simplicity and demonstration.
It is important to study Objective-C documentation until the following code is fully understood, td;dr does not work for this.
#import <Foundation/Foundation.h>
#interface Person: NSObject
#property int age;
#property int weight;
- (void)print;
#end
#implementation Person : NSObject
- (void)print {
printf("Age: %i, weight: %i", self.age, self.weight);
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
Person *don = [[Person alloc] init];
don.weight = 130;
don.age = 23;
[don print];
}
return 0;
}
Output:
Age: 23, weight: 130

Not known class method for selector OpenDevice

I'm developing an app in Objective-c for OSX.
I have write a first class and try to call this class in my MainThread.
The build succeed but the app crash
DeviceManager.h
#import <Foundation/Foundation.h>
#interface DeviceManager : NSObject
+(void)DeviceManager:OpenDevice;
#end
DeviceManager.m
#import "DeviceManager.h"
#implementation DeviceManager
- (id)init{
self = [super init];
if(self){
NSLog(#"Init");
}
return self;
}
+ (void)DeviceManager:OpenDevice {
NSLog(#"Opening Device");
}
#end
The main.m is calling it:
#import "DeviceManager.h"
int main(int argc, const char * argv[]) {
[DeviceManager OpenDevice];
return NSApplicationMain(argc, argv);
}
At build, I have Not known class method for selector OpenDevice
Thx
Seb
#import <Foundation/Foundation.h>
#interface DeviceManager : NSObject
+ (void) openDevice;
#end
DeviceManager.m
#import "DeviceManager.h"
#implementation DeviceManager
+ (void) openDevice {
NSLog(#"Opening Device");
}
#end
main.m
#import "DeviceManager.h"
int main(int argc, const char * argv[]) {
[DeviceManager openDevice];
return NSApplicationMain(argc, argv);
}
The above works for me. What does DeviceManager:OpenDevice mean? Because unless it's a new way to define methods it's gibberish. It looks like you want a class method for Device Manager called openDevice... so use + (void) openDevice {...}.

Objective-C: Use of undeclared identifier

I know I'm probably making a stupid mistake but I'm working my way through the book Programming in Objective-C and I'm getting a couple of errors but I cant seem to find the mistake.
person.m
#import "person.h"
#implementation person{
int age;
}
-(void) print{
NSLog(#"the person is %i years old", age);
}
-(void) setAge:(int)a{
age = a;
}
#end
person.h
#import <Foundation/Foundation.h>
#interface person : NSObject
-(void) print;
-(void) setAge: (int)a;
#end
main
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
person *newPerson; //error is on this line use of undeclared identifier:person
}
return 0;
}
You need to import person.h header in all files you want to use Person class, so add
#import "person.h"
line to your main file

expression error in Objective-C method call

I've dived into learning Objective-C and hit a little snag in when calling a method. Here's my simple code snippets:
Player.h code snippet:
#interface Player : NSObject{
}
-(void) performAction;
-(int) addNumber:(int) a toNumber:(int) b;
#end
Player.m code snippet:
#implementation Player
-(void)performAction{
NSLog(#"Here it is!");
}
-(int)addNumber:(int)a toNumber:(int)b{
return a+b;
}
#end
Calling method from main.m:
int val = [playerOne addNumber:(int)3 toNumber:(int)3];
In the above line of code, i keep getting an 'Expected expression' error.
Any ideas ?
This code works for me.
Player.h
#import <Foundation/Foundation.h>
#interface Player : NSObject
- (void)performAction;
- (int)addNumber:(int)a toNumber:(int)b;
#end
Player.m
#import "Player.h"
#implementation Player
- (void)performAction {
NSLog(#"Here it is!");
}
- (int)addNumber:(int)a toNumber:(int)b {
return a+b;
}
#end
main.m
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "Player.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
Player *playerOne = [Player new];
int val = [playerOne addNumber:(int)3 toNumber:(int)3];
NSLog(#"%d", val);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

Objective-c: Now allowing me to create an instance of a class

I just started programming in objective-c(today) and I'm just doing some simple command line examples but I've already run into something that has stumped me. I am getting a compiler error on lines 5 & 6 in main. Here is my code:
Fraction Interface:
#import <Foundation/Foundation.h>
#interface Fraction : NSObject
{
int numerator, denominator;
}
-(void)print;
-(void)setDenominator;
-(void)setNumerator;
#end
Fraction implementation:
#import "Fraction.h"
#implementation Fraction
-(void)print {
NSLog(#"%i/%i",numerator,denominator);
}
-(void)setNumerator: (int) n {
numerator = n;
}
-(void)setDenominator: (int) d {
denominator = d;
}
#end
Main:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
#autoreleasepool {
Fraction *f1 = [[Fraction alloc] init];
Fraction *f2 = [[Fraction alloc] init];
}
return 0;
}
All 3 files are in the same folder. I'm using Xcode; if this is relevant information.
Looks like you forgot to add #import "Fraction.h" to the top of main.m, In the future adding the error you receive would be helpful.