Objective C - Getter and setter properties for enum - iphone

I am a complete newbie at Objective-C. I have an enum as follows:
typedef enum _XLBadgeManagedType {
XLInboxManagedMethod = 0,
XLDeveloperManagedMethod = 1
} XLBadgeManagedType ;
I want to have getter and setter methods for it, such that if something happens, I set XLInboxManagedMethod to 1. How would I go about doing it?

Your code is just defining an enum type. It's a static, compile-time constant that is not changed. You use enums by declaring an instance of one, then changing it to one of the constant values you defined. If your enum looks like:
typedef enum _XLBadgeManagedType {
XLInboxManagedMethod = 0,
XLDeveloperManagedMethod = 1
} XLBadgeManagedType;
Then your property could look like:
#property (nonatomic, assign) XLBadgeManagedType myEnum;
And its use may look like:
- (void)someMethod {
self.myEnum = XLInboxManagedMethod;
self.myEnum = XLDeveloperManagedMethod;
// etc...
}

You do not change the values of enums. They stay as they are.

They are symbolic constants. You can not change it.

Related

Compare Objective-C enum values in Swift

I am attempting to do this in Swift:
var netStatus:NetworkStatus = reachability.currentReachabilityStatus();
if (!netStatus) { // error here says network status not convertible to bool
....
}
typedef enum : NSInteger {
NotReachable = 0,
ReachableViaWiFi,
ReachableViaWWAN
} NetworkStatus;
I've also tried
if (netStatus ==0)
if (netStatus == NetworkStatus.NotReachable) // NetworkStatus.type does not have a member named 'NotReachable'
etc.
Try using modern objective-c practices:
typedef NS_ENUM(NSInteger, NetworkStatus) {
NetworkStatusNotReachable,
NetworkStatusReachableViaWiFi,
NetworkStatusReachableViaWAN
};
Adopting Modern Objective-C
Read the Swift manual on how to define enum. it's more like
enum NetworkStatus:Int {
case NotReachable = 0
case Reach....
}
Unfortunately an enum is not transferrable to Swift from Objective-C, it needs to be an NS_ENUM.
If you can change the definition of the enum, then Daniel T.'s solution is best.
However, if you cannot change the enum definition, then you can create an intermediary class to provide an NS_ENUM and a mapping to the enum values.
See: https://stackoverflow.com/a/24950414/600753 for more details.

How to define typedef for a range of float numbers?

I want a property that will only accept float values between 0 and 1. I could do that in a standard way by defining float_t or double_t type for the property, but doubting, are there more elegant ways for that?
Do it the standard way - define a double/float property and check for validity in the setter - example:
#property (nonatomic, assign, readwrite) float property;
#synthesize property = _property;
- (void)setProperty:(float)property {
NSAssert(property >= 0.0f && property <= 1.0f, #"Invalid value passed to property setter.").
_property = property;
}
(Objective-)C doesn't support subrange types. For that you need Ada (or a few others). The best you can do is implement checks in your setters.

declare global variable in nsobject class (objective C)

I declare a variable and some methods in the global nsobject class like
#interface classGlobal : NSObject {
NSString *myGuid;
}
#property(nonatomic,assign)NSString *myGuid;
and i synthesize in the .m class. but when i try to access the myGuid variable in the same class (classGlobal.m) then it shows the error "instance variable 'myGuid' accessed in class method".
So please suggest how i solve this issue.
It means that instance variables cannot be accessed from class methods. A class method is declared using a + instead of a -. If you need to use global variables I suggest you take a look at this question which answers it pretty well. And here is another one.
The compiler complains, that you are using myGuid in a scope, where it is not accessible/defined. The declaration of myGuid in the interface part does not define a global variable, but an instance member variable. If you need a global variable (say, becaue you have to access it from a class method declared with + instead of -), declare as usual in your .m file:
MyClass.m:
static NSString* myGuid = nil;
+ (void) someClassMethod {
if( myGuid == nil ) ...
}

Why isn't my variable being assigned

Ok I think my understanding of properties in objective c may not be what I thought it was.
In my program I have a singleton that contains my class.
In my class during the init I assign a value from the singleton to my property.
I then assign a value to a property of that property.
However it does not keep the value and when I do a compare of the value in the singleton nothing has changed. What is going on here? Any ideas?
#interface MainGameLoop : NSObject {
MapData *mapData;
}
#property (retain) MapData *mapData;
-(id) init
{
self = [super init];
GlobalVariables *sharedManager = [GlobalVariables sharedManager];
self.mapData = sharedManager.mapData;
return self;
}
In a function of my class:
works:
sharedManager.mapData.currentPlayer = newCurrentPlayer;
does nothing:
self.mapData.currentPlayer == newCurrentPlayer;
self.mapData.currentPlayer == newCurrentPlayer;
Are you sure that you want two equal signs there? That statement is syntactically correct and will evaluate to either true or false.
== is a Boolean operator, while = is an assignment operator. Like what Dave said, if you are using an if statement such as if (self.mapData.currentPlayer == newCurrentPlayer) {…}, you would want to use == because it would evaluate to true or false, while = would be used to set the value of a variable, which is what I think you are trying to do.
If it's any consolation, I've made that mistake too many times to count…
Something that I do is to use NSLog() or printf() to make sure that each step is working correctly.

Static string variable in Objective C on iphone

How to create & access static string in iPhone (objective c)?
I declare static NSString *str = #"OldValue" in class A.
If i assign some value to this in class B as str = #"NewValue".
This value persists for all methods in class B. But if I access it in class C (after assignment in B) I am getting it as OldValue.
Am I missing something? Should i use extern in other classes?
Thanks & Regards,
Yogini
Update: As of Xcode 8, Objective-C does have class properties. Note, it's mostly syntactic sugar; these properties are not auto-synthesized, so the implementation is basically unchanged from before.
// MyClass.h
#interface MyClass : NSObject
#property( class, copy ) NSString* str;
#end
// MyClass.m
#import "MyClass.h"
#implementation MyClass
static NSString* str;
+ (NSString*) str
{
return str;
}
+ (void) setStr:(NSString*)newStr
{
if( str != newStr ) {
str = [newStr copy];
}
}
#end
// Client code
MyClass.str = #"Some String";
NSLog( #"%#", MyClass.str ); // "Some String"
See WWDC 2016 What's New in LLVM. The class property part starts at around the 5 minute mark.
Original Answer:
Objective-C doesn't have class variables, which is what I think you're looking for. You can kinda fake it with static variables, as you're doing.
I would recommend putting the static NSString in the implementation file of your class, and provide class methods to access/mutate it. Something like this:
// MyClass.h
#interface MyClass : NSObject {
}
+ (NSString*)str;
+ (void)setStr:(NSString*)newStr;
#end
// MyClass.m
#import "MyClass.h"
static NSString* str;
#implementation MyClass
+ (NSString*)str {
return str;
}
+ (void)setStr:(NSString*)newStr {
if (str != newStr) {
[str release];
str = [newStr copy];
}
}
#end
Unlike Java, where a static variable is scoped for all instances of a class, static in C means that a variable is accessible only from within the file where it is declared. It allows you to do things like declare a static variable inside a function, which sets the value only the first time through, like this.
One thing you haven't mentioned is the relationship between classes A, B, and C. If they are in an inheritance hierarchy, and you're expecting the static variable to be inherited as in Java, the method described by zpasternack will work.
If the three classes are unrelated, and you just want to access the value declared in A, then extern is a more appropriate way to go. In this case, you want to declare the variable as extern in ClassA.h, then define it in Class.m. As long as ClassB and ClassC import ClassA.h, they will be able to link against the same extern definition.
One fine point is that, instead of using extern by itself, it's more robust to use OBJC_EXPORT, which is defined in objc-api.h and handles compiling under C++ as well. Here's a code sample:
// ClassA.h
OBJC_EXPORT NSString* commonString;
...
// ClassA.m
NSString* commonString = #"OldValue";
// ClassB.m
#import "ClassA.h"
...
commonString = #"NewValue"; // Can be inside a function or method
Of course, using externed variables in this way creates an infamous, much-maligned global variable, which is fragile in that anyone can read or write it, and access is uncontrolled. This is the simple approach, and answers your question about using static vs. extern. However, as a design principle, the encapsulation provided by wrapping the variable with class methods is much safer, albeit more complex. In object-oriented languages, when the effect you're trying to achieve is that of a class-static method, encapsulation is probably the right way to go.