In Objective C, is there a way to call reference a typdef enum from another class? - objective-c

It is my understanding that typedef enums are globally scoped, but if I created an enum outside of the #interface of RandomViewController.h, I can't figure out how to access it from OtherViewController.m. Is there a way to do this?
So...
"RandomViewController.h"
#import <UIKit/UIKit.h>
typedef enum {
EnumOne,
EnumTwo
}EnumType;
#interface RandomViewController : UIViewController { }
and then...
"OtherViewController.m"
-(void) checkArray{
BOOL inArray = [randomViewController checkArray:(EnumType)EnumOne];
}

In OtherViewController.m:
#import "RandomViewController.h"
And you shouldn't name your variable like the type. Rather name it myEnumOne, or whatever you like :)
BOOL inArray = [randomViewController checkArray:(EnumType)myEnumOne];
Can you show us the declaration of the checkArray method? In my understanding it should be
- (BOOL)checkArray:(EnumType)blabla;
You shouldn't need to typecast the argument to EnumType when calling the method (I'm assuming that it's of the type EnumType already).

Just import the header.

Related

Add ivars in #implementation

For good encapsulation, decent Objective-C programmers put their private ivars in a private extension declared in the main implementation file, like this:
// MyClass.m
#interface MyClass () {
float value;
}
#end
#implementation MyClass
#end
But recently, I found a simpler way to hide private ivars: ivars can be declared in a {} block following #implementation, like this:
// MyClass.m
#implementation MyClass {
float value;
}
#end
It is really handy when no private methods but only private ivars need to be hidden.
However, I'm not sure about its syntax validity. Can anyone validate or invalidate it with some canonical references?
It's perfectly valid and here is a document by Apple talking about it:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW6
I don't personally use it as I prefer the syntax of a class continuation category.
I was also curious about this. Here is the updated link from Apple:
You Can Define Instance Variables without Properties
It’s best practice to use a property on an object any time you need to keep track of a value or another object.
If you do need to define your own instance variables without declaring a property, you can add them inside braces at the top of the class interface or implementation, like this:
#interface SomeClass : NSObject {
NSString *_myNonPropertyInstanceVariable;
}
...
#end
#implementation SomeClass {
NSString *_anotherCustomInstanceVariable;
}
...
#end

Call a variable from one file to the other

Of Objective C, I'm looking to call a variable from one .m to the other .m
This is given myvar declared as an int in Example1.h
Example1.m
myvar = myvar+10
Example2.m
if (myvar == 10){NSLOG("#myvar equals the correct integer: %i",myvar);}
However, by default myvar will equal 0 because myvar is called from Example1.h in Example2.m.
For global values, create a class to hold these and define the variables as static. You can also define class level methods to manipulate the static variable. I call my class appState. You might define myVar as static and then class methods (use the + not -) to get and set this variable.
Here's an example of a BOOL I can access from anywhere in my application.
account.h
#import <Foundation/Foundation.h>
#interface Account : NSObject
{
}
+(BOOL)isOffLine;
+(void)setOffLine:(BOOL)newValue;
#end
account.m
#import "Account.h"
#implementation Account
static BOOL _offline;
+(BOOL)isOffLine;
{
return _offline;
}
+(void)setOffLine:(BOOL)newValue
{
_offline = newValue;
}
#end
Now from any class in my application, I can #import account.h and then use something like:
if ([Account isOffLine]) {...}
or
[Account setOffLine:YES];
Note that I didn't create an instance of this class. I'm calling the class level methods. The value will persist between calls from different classes in my application.
I’d recommend you read up on the basics, perhaps Object-Oriented Programming with Objective-C could be a good place to start. My guess is that what you really should be doing is creating a property in one class and accessing it from another.

#class for typedef enum?

In one header file, I have something like:
// PasscodeInputViewController.h
typedef enum {
PasscodeInputModeOn, // set passcode
PasscodeInputModeEnter, // enter passcode
PasscodeInputModeChange, // change passcode
PasscodeInputModeOff // turn off passcode
} PasscodeInputMode;
In another header file, I declare a method that takes an argument of type PasscodeInputMode:
#import "PasscodeInputViewController.h"
- (void)presentPasscodeInputWithMode:(PasscodeInputMode)mode;
As you can see, I use #import "PasscodeInputViewController.h" as above so that PasscodeInputMode is recognized, but is there a #class equivalent for typedef enum?
No, there isn’t an equivalent.
Enumerations in Objective-C are the same as enumerations in C. Since the underlying type of an enumeration is implementation-dependent (e.g., it could be char or int), the compiler must know the complete declaration of the enumeration.
That said, a type specifier
enum nameOfEnum
without listing the enumeration members is valid C provided it appears after the type it specifies is complete, i.e., enum nameOfEnum { … } must appear beforehand in the translation unit.
In summary: There’s no forward declaration of enumerations, only backward references.
#Caleb, #Bavarious:
Most recent way (Jan, 2017) to forward declare the enum (NS_ENUM/NS_OPTION) in objective-c is to use the following:
// Forward declaration for XYZCharacterType in other header say XYZCharacter.h
typedef NS_ENUM(NSUInteger, XYZCharacterType);
// Enum declaration header: "XYZEnumType.h"
#ifndef XYZCharacterType_h
#define XYZCharacterType_h
typedef NS_ENUM(NSUInteger, XYZEnumType) {
XYZCharacterTypeNotSet,
XYZCharacterTypeAgent,
XYZCharacterTypeKiller,
};
#endif /* XYZCharacterType_h */`
Similar question Forward-declare enum in Objective-C
Forward declaration of classes is necessary to enable two classes to refer to each other. It's not uncommon to have two classes that are defined in terms of each other:
#class ClassB;
#interface ClassA : NSObject
{
ClassB *objectB;
}
#end
#interface ClassB : NSObject
{
ClassA *objectA;
}
#end
There's no way to make that compile without the forward declaration.
The same is not true of enumerations. enum just creates a set of named values... you can't include one enumeration in the definition of another. Therefore, there's never a need to forward declare an enumeration.
I think what you want is a class that has PasscodeInputMode as a property of it. That way you can be passing around an instantiated object of that class, and can set/get that property, and do other object-like-things with it (assume that's why you'd want to find a "#class equivalent"

how to return C++ pointer in objective-C++

I have the following objective-C++ header with the simple method to return this pointer.
#interface MyObj
{
MyCPPObj * cpp;
}
-(MyCPPObj *) getObj;
I have created the simple method
#implementation MyObj
-(MyCPPObj *) getObj
{
return cpp;
}
Everything seems to work until I actually try to use the object in another file
newObj = [createdMyObj getObj];
It complains: error: cannot convert 'objc_object*' to 'MyCPPObje *' in initialization.
It seems that the method is return an objective-c object, but I specifically requested a C++ pointer.
MyCPPObj is an honest C++ class:
class MyCPPObj
{
public:
int x;
}
How can I fix that?
On my 10.6.3 machine, the following combination worked without any problem: aho.h
#import <Foundation/Foundation.h>
class MyCPPObj{
};
#interface MyObj:NSObject
{
MyCPPObj * cpp;
}
-(MyCPPObj *) getObj;
#end
and aho.mm
#import <Foundation/Foundation.h>
#import "aho.h"
void foo(){
MyObj*objcObj=[[MyObj alloc] init];
MyCPPObj*cppObj=[objcObj getObj];
}
Two pitfalls you might have fallen into:
Unlike C++, a class in Objective-C which doesn't inherit from NSObject won't work. (Well, you can make it work, but you don't want that usually.) Note the line #interface MyObj:NSObject.
To use NSObject, do #import <Foundation/Foundation.h>
Don't forget to use the extension .mm for Objective-C++ files.
Most likely you have forgotten to #import the header file with the #interface into the .mm file where you use getObj.
The error states what happens, and JeremyP is right on the money. When you forget to include a header file with the prototypes of the selectors, the compiler assumes the selector returns an object of type id. Well id is a typedef to objc_object*, which is incompatible with your C++ class. To fix the error, you simply need to include your header file in the file where you called getObj.

Structure as a class member in Objective C

Is it possible a structure as a class member in objective C? If yes how can I assign values to that structure from another class?
Yes, you can. You either just expose the structure as a property (in which case you have to set/get the whole thing) or you write custom accessors that walk into the fields of the strucutre.
For a concrete example, CGRect is a structure (though it is hidden by a typdef), which means the frame property of UIView get and set a structure.
In other words:
CGRect myFrame = CGRectMake(0,0,320,480); //CGRect is a struct
myView.frame = myFrmae; //Setting a struct
You just use dot notation to assign and access the values. You can also use -> if you have a pointer to a struct.
typedef struct {
int a;
double b;
} SomeType;
// Define some class which uses SomeType
SomeType myVar;
myVar.a = 1;
myVar.b = 1.0;
SomeType* myPtr = &myVar;
NSLog (#"%i", myPtr->a);
// This works...
SomeType mySecondVar = myVar;
// But you have to be careful in cases where you have pointers rather than values.
// So this wouldn't work if either element was a C string or an array.
Yes and there is an easy way to access that struct using Objective-C 2.0 Properties. Consider the following struct from Stephens post.
typedef struct {
int a;
double b;
} SomeType;
In your .h file you would declare the member in your #interface
#interface AClass : NSObject{
SomeType member;
}
#property SomeType member;
#end
Remember that if you choose to go with pointers here you will need to manage your own memory.
And in your #implementation (your .m file) don't forget add a #synthesize
#implementation AClass
#synthesize member;
#end
I hope this helps.