What is the difference between using
#class & #import? I had a situation
where i was getting a build error,
and the solution was to use #class
instead of #import to import my
class.
What does nonatomic mean? When do i
use nonatomic to define a property,
and when do i avoid it?
#class allows you to create a stub for a class that you will later define. For example:
MyOtherClass.h
#class MyClass;
#interface MyOtherClass : NSObject {
MyClass *myObject;
}
MyOtherClass.m
#include "MyOtherClass.h"
#interface MyClass : NSObject {
NSUInteger myInt;
}
#define is used to define strings that will be replaced by the preprocessor. For example:
#define MY_INT 5
x = MY_INT;
will be rewritten by the pre-processor as:
x = 5;
Scott G has already answered your question literally, but if, as Adam Ko said, you have meant #import, the answer would be that #class does not import the class but just tells the compiler that sometime later a class with the given name will be provided (in what is called "deferred binding" as I remember).
The #class is used mainly when you have two classes referring to each other, so they can not both import each other (that is probably the source of your compiler errors).
However, #class has a clear restriction that the compiler does not allow you to refer to any methods or attributes of the defined class. But usually you only need to use them in an implementation .m file, and there you can import the class without any problems.
An atomic property is one for which the getter is guaranteed to return a valid, meaningful value even if the relevant setter is being called simultaneously on another thread. That costs more in processing terms than a nonatomic property, but is safer for multithreaded code.
If you use atomic (which is default) it does some magic to make your code perfectly thread-safe.
This magic costs something and that's why you see keyword nonatomic often, people use it if they don't really care about thread safety to make their code faster.
Related
I have two classes, Entity, and EntityHandler.
EntityHandler has a method, AddEntity. This method adds the Entity to an NSMutableArray.
Entity has a method called subscribe. It assigns a reference to EntityHandler to a variable for later usage.
Upon the inclusion of both header files in each other the project breaks. For example,
-(void) addEntity: (Entity *) mob;
returns the error
Expected a type
How can I fix this?
You're looking to employ forward declarations for your ObjC types, in order to break the cyclic header dependency.
It would look something like:
// EntityHandler.h
#class Entity; // << the forward declaration. not #import.
#interface EntityHandler : NSObject
-(void) addEntity:(Entity *) mob;
#end
This tells the compiler that there is an ObjC class named Entity.
Then you #import when you need more than a typename (likely in EntityHandler.m).
I created two classes in objective c and I would like to use one of them as a property of the other. To be more concrete, one of the classes is a 'term' that contains an integer variable and an nsstring that acts as the variable. The other class is an 'expression' that has an nsmutable array as an instance variable that contains 'terms' as its objects. What I want to do is have add the possibility of having one of the terms have an 'expression' as a property to implement something like distributing over parentheses and substituting an expression for a variable. However, Xcode is telling me that 'expression' is not an acceptable type name despite the fact that I have imported my expression header file. I think I may have read somewhere that only foundation classes are available to use as properties. What can I do to add this class as an instance variable?
I suspect you have an import cycle, like this:
Expression.h
#import "Term.h"
#interface Expression : NSObject
...
Term.h
#import "Expression.h"
#interface Term : NSObject
...
Notice how each file imports the other? That won't work. Instead, you need to use forward declarations:
Expression.h
#class Term; // tell the compiler that Term is a class name
#interface Expression : NSObject
...
Term.h
#class Expression; // tell the compiler that Expression is a class name
#interface Term : NSObject
...
Then, in your .m files, you can safely import both .h files:
Expression.m
#import "Expression.h"
#import "Term.h"
#implementation Expression
...
Term.m
#import "Term.h"
#import "Expression.h"
#implementation Term
...
Although the above answers are also correct, in my case the problem which occured was "#end" was missing in prototype/interface declaration.
I am just learning OOP from a book I picked up (Big Nerd Ranch), and it just went through the getter and setter chapter. I would just like to clarify I understand what I have just done. Instead of creating a method to set the value of an instance, and then another method to extract the value and display it, I create use the #property and #synthesize syntax to define both methods.
Instead of doing this:
-(void) setHeightOfObject:(int)h;
-(void) setWeightOfObject:(float)w;
-(int) heightOfObject;
-(float) weightOfObject;
and defining it like this:
- (int)heightOfObject
{
return heightOfObject;
}
- (void)setHeightOfObject:(int)h
{
heightInMeters = h;
}
- (float)weightOfObject
{
return weightOfObject;
}
- (void)setWeightOfObject:(float)w
{
weightOfObject = w;
}
I would do this with getter and setters in the .h file:
#property int heightOfObject;
#property float weightOfObject;
And then go to my .m file and link it:
#synthesize heightInMeters, weightOfObject;
This then gives me the ability to set the value of my object, and then get it if I need it printed? I know this is an important concept and I want to make sure I have the proper grasp of it.
You are correct. The #synthesize essential expands out to the implementation you wrote while compiling.
Since writing getters and setters is boring and repetitive (and most objects have a bunch of properties you'd want getters and setters for) having this little shortcut makes you spend less time on boilerplate code and more time implementing something interesting.
If you'd like more detailed information about objective-c's properties, you can have a look at the programming guide (although this might be somewhat unnecessarily detailed for you at this point).
There are two parts to what you are achieving by using #property and #synthesize.
#property tells the compiler that it should allow you to use dot syntax to call the accessors of heightOfObject and weightOfObject. So doing this
int height = myObject.heightOfObject;
myObject.weightOfObject = 10;
becomes legal code and is exactly equivalent to this:
int height = [myObject heightOfObject];
[myObject setWeightOfObject:10];
You can use #property without #synthesize, in which case you must implement the accessors exactly as you have done in your question.
Using #synthesize tells the compiler that it should generate the accessors for you and it will also generate the instance variables themselves if your runtime supports it (e.g. on iOS and 64-bit OS X).
Property and synthesise were introduced in Objective C 2.0 in order to provide a straightforward way to create getters and setters.
Check this link it will be of help:
http://cocoacast.com/?q=node/103
You not only get getters and setters. You also get a neat syntax: self.heightOfObject which you can assign to or read from.
#property has a lot of settings though so you might want to read in detail. In particular you can control whether you need both read and write access or only one of them.
I've been reading up on the automatically synthesized ivars. My question is, "WHere are automatically they allocated?" I would have expected them to be part of self, so that I could see them in the debugger, but it seems that the only way I can see them is by invoking the accessor method (via the gdb 'po' command). Isn't there space in the class/object's struct (as there would be for an explicitly declared ivar)?
(Is there a description of the in-memory representation for a modern Objective-C object?)
Being a C guy, it makes me very uncomfortable to not to be able to see where everything is. :-P
Looks like this will tell you:
How do automatic #synthesized ivars affect the *real* sizeof(MyClass)?
I am a C guy at heart too. Why bother using these auto generated ones? I like looking at a class and seeing what it holds onto in terms of data.
Interesting: Neat how they took the 64 bit change to make things better.
http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html
They are added to the objective-c object (which is a C structure) no different to a regular ivar, so for example:
#interface TestObject : NSObject {
}
#property (nonatomic, assign) int theInt;
#end
#implementation QuartzTestView
#synthesize theInt;
#end
You can refer to theInt ivar directly (not through property accessors) either:
- (void)someMethod {
theInt = 5;
}
OR
- (void)someOtherMethod {
self->theInt = 10;
}
See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html - using the modern runtime an instance variable "will be synthesized for you". It can be nice to add a variable yourself instead though (so that you can see it when debugging in self), however you have to be careful not to do direct assignments to the instance variable for retain or copy based properties.
This is just out of curiosity but when i declare an enum type, would it be better to have it within an implementation declaration or outside of it? What would be best practice? For example:
#implementation PostQuestionScene
enum popUpItems{
kExpiredBox,
kPauseBackground
};
vs..
enum popUpItems{
kExpiredBox,
};
#implementation PostQuestionScene ..
I tend to always have a typedef so it's just like another variable:
typedef enum {
kExpiredBox,
kPauseBackground
} popUpItems_t;
Then create instances of it.
popUpItems_t popUpItems;
If you will use it outside that module, put the typedef in the header so when the header is included, other modules have the typedef at their disposal (if they need to take it as an argument, for example,) otherwise put it in the implementation (think public/private variables.)
I don't think it makes any technical difference. I would place it before the #implementation (along with all other miscellaneous declarations) unless it is just used in one or a small group of methods, in which case I would place it immediately before those methods.
Of course, if it might be used by clients or subclasses it should be in your header file (where #interface is) so that the definition is visible to them.