I'm trying to create a class with global constants:
//Resources.h
#import <Foundation/Foundation.h>
#interface Resources : NSObject
{
extern NSString * const MY_CONST;
}
#end
and
//Resources.m
#import "Resources.h"
#implementation Resources
NSString * const MY_CONST = #"my constant";
#end
And getting this nasty error: expected specifier-qualifier-list before 'extern'
What do I need to do?
Thank you
put
extern NSString * const MY_CONST;
outside of class interface declaration. MY_CONST is not a class member, so why put it inside?
Related
If I put a const to the objective C class,
#implementation CLASS_A
const NSString* TAG=#"CLASS_A";
#end
I found const TAG become global variable. And I cannot put two #implementation, each which has a TAG, in one .m file
#implementation CLASS_A
const NSString* TAG=#"CLASS_A";
#end
#implementation CLASS_B
const NSString* TAG=#"CLASS_B"; (Error)
#end
I would like TAG to link to each class with different name. Where will I put the const NSString* TAG=#"CLASS_A" and TAG=#"CLASS_B" in the class?
I also tried this, but got errors.
#implementation CLASS_A
{
const NSString* TAG=#"CLASS_A"; (Error)
}
#end
Create a class method to get the tag externally:
#interface MyClass : NSObject
+ (NSString *)tag;
...
#end
and define it using a static in the implementation file (.m):
#import "MyClass.h"
static NSString * const _tag = #"A tag";
#implementation MyClass
+ (NSString *)tag
{
return _tag;
}
Note: you should implement one class per implementation file.
I want to create a new object, one of the property is (readonly).
Here is my code:
1/ My class (.h + .m)
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
#property (readonly) NSString* myProperty;
#end
#import "MyClass.h"
#implementation MyClass
#end
2/ My class extension (.h)
#import "MyClass.h"
#interface MyClass ()
#property (readwrite) NSString* myProperty;
#end
3/ MyClassCategory (.h + .m)
#import "MyClass.h"
#interface MyClass (MyClassCategory)
+ (MyClass*) creatNewObject:(NSString*) mypro;
#end
#import "MyClass+MyClassCategory.h"
#import "MyClass_MyClassExtension.h"
#implementation MyClass (MyClassCategory)
+ (MyClass*) creatNewObject:(NSString*) mypro {
MyClass* newObject = [[MyClass alloc] init];
newObject.myProperty = mypro;
NSLog(#"New object have been created%#", newObject);
return newObject;
}
#end
#import <Foundation/Foundation.h>
#import "MyClass.h"
#import "MyClass+MyClassCategory.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
MyClass* newObject1 = [MyClass creatNewObject:(#"I am the new object!")];
NSLog(#"New object have been created%#", newObject1);
}
return 0;
}
after running the code in the main method, I got
2014-09-25 21:53:52.204 MyClass[2811:303] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyClass setMyProperty:]: unrecognized selector sent to instance 0x100109e10'
014-09-25 22:36:05.746 MyClass[2989:303] -[MyClass setMyProperty:]: unrecognized selector sent to instance 0x100200130
I want to be enables edits to the properties of an existing class instance from category.
Can you help me please?
Thank you.
In MyClass.m, you also need to include the extension header.
#import "MyClass_MyClassExtension.h"
Otherwise the compiler won't see myProperty is redeclared as a read-write property while generating the implementation of MyClass.
I am really new to Objective-C and when I was practicing the book exercises, I really am stuck here. Please help me solve this and I have been thinking what could cause this error for more than three hours. Still I didn't get it!
Best regards,
Raj.
Thanks in advance !
main.m
#import <Foundation/Foundation.h>
#import "XYZPerson.h"
#import "XYZShout.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
//XYZPerson *some = [[XYZPerson alloc]init];
XYZShout *some = [[XYZShout alloc]init];
[some sayHello];
// insert code here...
// NSLog(#"Hello, World!");
}
return 0;
}
XYZPerson.h
#import <Foundation/Foundation.h>
#interface XYZPerson : NSObject
#property NSString *firstName;
#property NSString *secondName;
#property NSDate *dob;
-(void) saySomething;
-(void) sayHello;
#end
XYZPerson.m
#import "XYZPerson.h"
#implementation XYZPerson
-(void) sayHello {
[self saySomething:#"Hello all"];
}
-(void) saySomething:(NSString *)greet {
NSLog(#"%#", greet);
}
#end
XYZShout.h
#import "XYZPerson.h"
#interface XYZShout : XYZPerson
// -(void) saySomething;
#end
XYZShout.m
#import "XYZShout.h"
#implementation XYZShout
-(void) saySomething:(NSString *)greet {
NSString *upperGreet = [greet uppercaseString];
[super saySomething:upperGreet]; // this is where I get the error mentioned above
}
#end
Got it working ! Thanks to #MatthewD , #trojanfoe , #JFS for your big help :)
It looks like you are testing inheritance so I will assume that XYZShout is supposed to be derived from XYZPerson. If so follow the suggestion from #JFS and make sure it does actually derive:
XYZShout.h:
#import <Foundation/Foundation.h>
#import "XYZPerson.h"
#interface XYZShout : XYZPerson
- (void)saySomething:(NSString *)greet;
#end
And also correct the definition of saySomething in XYZPerson (you missed off the parameter):
XYZPerson.h:
#import <Foundation/Foundation.h>
#interface XYZPerson : NSObject
#property NSString *firstName;
#property NSString *secondName;
#property NSDate *dob;
- (void)saySomething:(NSString *)greet;
// ^^^^^^^^^^^^^^^^^
- (void)sayHello;
#end
(Moved from comments into an answer...)
MatthewD: What happens if you change - (void) saySomething; in XYZPerson.h to - (void) saySomething:greet;?
Raj0689: Why does it run when I change it to saySomething:greet and not saySomething ? Since greet is defined only along with saySomething !!
When you call a method, the compiler needs to locate the signature of that method so it can verify that the method is being called correctly. The signature includes the method name and the number and types of parameters. The usual way of providing method signatures is by importing the header file that defines those signatures.
So, in XYZShout.m where you call:
[super saySomething:upperGreet];
The compiler searches XYZShout.h, which is imported by XYZShout.m, and XYZPerson.h, which is imported by XYZShout.h. In XYZShout.h, the following method was being found:
-(void) saySomething;
This matches the called method in name, but not in parameters, so the compiler does not consider this a match. No other definitions of saySomething are found anywhere, so it gives an error instead.
Please make sure to set the XYZShout.h interface to #interface XYZShout : XYZPerson?
I have Class A and Class B.
Class B subclasses Class A
Class A has a static constant NSString variable
In a method of Class B I need to use the static constant NSString variable of Class A. What are my options ?
I tried declaring the same thing again, but caused problem (internal inconsistency), tried without using (says, variable undeclared).
Any idea how I can solve this problem ?
Thanks.
Make a class method returning that constant, like this:
+(NSString*) constString {
return myConstString;
}
You can declare static constant strings in the .h file. That way they are public and can be used by other classes that import the header file, including your subclass.
Alternatively, you can declare a reference to the string in your Class B using extern:
extern NSString *const MyString;
That basically tells the compiler that the value of that string is defined elsewhere in the code and it doesn't have to worry about it.
By "Class A has a static constant NSString variable", I assume you're referring to having something like the following defined in your Class A .m file:
static NSString * const MyString = #"MyString";
#implementation ClassA
#end
To allow Class A and its subclasses to see the value, you can do something like this:
MDClassAPrivate.h:
#import <Foundation/Foundation.h>
static NSString * const MDBlahBlahKey = #"MDBlahBlah";
MDClassA.h:
#import <Foundation/Foundation.h>
#interface MDClassA : NSObject {
}
#end
MDClassA.m:
#import "MDClassA.h"
#import "MDClassAPrivate.h"
#implementation MDClassA
#end
MDClassB.h:
#import "MDClassA.h"
#interface MDClassB : MDClassA {
}
#end
MDClassB.m:
#import "MDClassB.h"
#import "MDClassAPrivate.h"
#implementation MDClassB
#end
By moving the static const variables to a separate file, you can allow any class to import them in the implementation file.
My personal solution to this problem would be a pseudo-protected method that returns the constant string.
// ClassA.m
#interface ClassA ()
- (NSString *)constantString;
#end
#implementation ClassA
- (NSString *)constantString {
return #"MyConstantString";
}
#end
Then following on into your subclass:
// ClassB.m
#interface ClassA ()
// This is a method redeclaration to avoid build warnings
- (NSString *)constantString;
#end
#implementation ClassB
- (void)someMethod {
NSString *theConstantString = [self constantString];
// do stuff...
}
#end
The assumption here is that your constant string really is constant, if you want it to be dynamic you would need to modify this solution slightly, but it can still handle it.
You can use 'userDefaults' to set a value that is accessible in the whole application.
[[NSUserDefaults standardUserDefaults] setObject:object forKey:#"objectKey"];
Good day, friends.
I'm newbie in Objective-C. I'm wanting to use enum in my class and make it public.
I've understand how to declare enums (http://stackoverflow.com/questions/1662183/using-enum-in-objective-c), but I don't understand where should I declare them.
I've tried:
#interface MyFirstClass : NSObject {
typedef enum myTypes {VALUE_A, VALUE_B, VALUE_C} MyTypes;
}
or:
#interface MyFirstClass : NSObject {
#public
typedef enum myTypes {VALUE_A, VALUE_B, VALUE_C} MyTypes;
}
But compiler throws error: "expected specifier-qualifier-list before typedef".
What's wrong?
.h
typedef enum myTypes {VALUE_A, VALUE_B, VALUE_C} MyTypes;
#interface MyFirstClass : NSObject {
MyTypes type;
}
.m file
type=VALUE_A;
Outside of the #interface declaration.
typedef enum myTypes {VALUE_A, VALUE_B, VALUE_C} MyTypes;
#interface MyFirstClass : NSObject {
}
#end
You can create a header file (*.h) and do following to match your enum variable.
// EnumConstants.h
#ifndef EnumConstants_h
#define EnumConstants_h
typedef enum {
VEHICLE,
USERNAME
} EDIT_TYPE;
typedef enum {
HIGH_FLOW,
STANDARD_FLOW
} FLOW_TYPE;
#endif
Uses:
#import "EnumConstants.h"
UISwitch *onOffSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(self.tableview.frame.size.width-75, 26, 0, 0)];
onOffSwitch.tag =STANDARD_FLOW;