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.
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).
A class can be extended in Objective C using a category such as:
#interface NSString (CategoryName)
-(NSString *)myFabulousAddition; // a fabulous additional method
#end
/////////////////////////////
#implementation NSString (CategoryName)
-(NSString *)myFabulousAddition {
// do something fabulous...
}
#end
In this small example, I would be adding the method myFabulousAddition to NSString. I could then call it by [anNSString myFabulousAddition] just as if it were part of the NSString set of methods. Great and useful.
In the Apple documents regarding Categories, the docs state:
There’s no limit to the number of
categories that you can add to a
class, but each category name must be
different, and each should declare and
define a different set of methods.
What if you have something like this:
#interface NSString (CategoryName)
-(NSString *)myFabulousAddition; // a fabulous additional method
#end
#interface NSString (ANOTHERCategoryName)
-(NSString *)myFabulousAddition; // a DIFFERENT fabulous additional method
// BUT with same name as the other category
#end
/////////////////////////////
#implementation NSString (CategoryName)
-(NSString *)myFabulousAddition {
// do something fabulous...
}
#end
#implementation NSString (ANOTHERCategoryName)
-(NSString *)myFabulousAddition {
// do something equally fabulous, but DIFFERENT...
}
#end
The lack of a name in the parenthesis indicates that the form is an extension to the class, like so:
#interface MyObject () // No name -- an extension vs category to MyObject
- (void)setNumber:(NSNumber *)newNumber;
#end
Does the category name have any meaning to the compiler or linker? Is the category name part of the method signature in anyway or is it part of a primitive namespace? If the category name is meaningless, how do you know if you are about to stomp on another method and get undefined behavior?
The way to avoid stomping on methods is to prefix your category method names, like this:
#interface NSString (MyCompanyCategoryName)
- (NSString *)MYCO_fabulousAddition;
#end
If you get a collision of method names from different categories, then which one 'wins' at run time is completely undefined.
The name of a category is almost entirely useless, with the exception being that the nameless category (i.e. ()) is reserved for class extensions. Methods from class extensions are supposed to be implemented in the class' main #implementation.
The category name doesn't mean anything special, it's just an identifier. Unless the linker (or runtime loader) decides to give you a warning, there is no way to tell that multiple categories are defining the same method.
The behavior is (largely) unpredictable - one of the categories will win out, but you can't tell which one. Also, I think it's well possible you will start out with one implementation and end up with another one (if the second category is loaded after the first).
It certainly acts as an identifier, from the programmer's point of view. In the compiler point of view category methods are simply added as an extension of the class ( from which it is extending), regardless of the name.
And yes you can add categories of the same class with the same identifiers, even with same functions. But you definitely can't override any function because categories are just part of the class once you define them ( Just like you can't override a function of a class from within that class ).
As they are being added at runtime, they don't raise any error and only at runtime compiler selects the function, which is totally unpredictable.
i believe that they don't have any meaning. You don't really use them in your code ... Since they are categories and ... the semantic of a category ... is just to categorize something, i think this is somewhat logical ...
I would say they just simply gather the methods ...
On the other hand your question is very valid ... You DON'T KNOW if you override a method. If you are in the same project then the compiler issues a warning (or an error ? i don't remember), however if you are overriding a method from a library, then .. you are out of luck ...
My question is a simple fundamental question for creating a subcategory of a category in objective-c.
Consider a file named NSString+categoryName.h given as follows:
#import <Foundation/Foundation.h>
#interface NSString (categoryName)
...
#end
with a corresponding implementation file named categoryName.m (not shown).
How would I make a subcategory if this? Here is my initial thought (contained in a separate file called NSString+categoryName+subCategoryName.h):
//Should there be an import statement here to prepare compiler for appearance of categoryName?
#import <Foundation/Foundation.h>
#interface categoryName (subCategoryName)
...
#end
possessing a separate implementation file of a similar name NSString+categoryName+subCategoryName.m:
// Is the import correct here? Do I need to somehow reference this in my .h file?
#import "NSString+categoryName.h"
#implementation categoryName (subCategoryName)
...
#end
Any help with this matter is greatly appreciated, as always!
I have never heard of a "subcategory" in Obj-C. You can create as many categories as you like for the same class, and you can adopt a naming convention like #interface Class (category_subcategory) ... #end or similar, but your idea of making a category on a category does not seem workable.
Categories are not hierarchical in Objective-C. They're just a way to put methods into groups that aren't all loaded at once.
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.
I am new to Objective-C and want to know about inheritance. I am aware of the concepts but confused with the methods that programmer uses to inherit a class.
I have two classes: class A and class B, and want to make B a child of A.
Sometimes a programmer uses #import "class A" and sometimes uses the # sign. Which one of them should be used, and why? Is there any difference between their uses?
Another question I have is about the ":" sign which we write after class declaration, for example #interface class_A : class_name
In past I was a student of Java and C#, and their inheritance is similar to each other. But is Objective-C (I am currently working for iPhone) the same?
There is a difference between those terms, and I can see where your confusion is.
The #import is used to load definitions of a class's h file. This is, in a way, similar to C#'s using keyword, but in Objective-C we need to specify everything in the class level, not in the namespace level -- there's no concept of namespace level encapsulation in Objective-C.
The #class keyword is used whenever you need to declare that an object is valid -- but if you're going to use the internals of that object you will eventually need to add an #import of the class anyway. There's a great answer here on the difference between #class and #import.
As with C# and Java, inheritance is achieved by using the : operator in your h file. So in your declaration of Class B, it should go like:
#interface Class_B : Class_A
Hope this clears everything up.
update for your comment:
Let's say I want to inherit class A into class B, and use class C as a variable somewhere. You'll need the ff to make it work:
#import "Class_A.h"
#class Class_C;
#interface Class_B : Class_A {
Class_C *myvariable
}
Now, lets say somewhere inside your file you need to access a Class_C member e.g., myvariable.Property1, that's the time you turn #class Class_C into #import "Class_C.h".
I don't think declaring it like this:
#class Class_A;
#interface Class_B : Class_A
would work... you'll still need an #import "Class_A.h" somewhere which makes the #class declaration somewhat redundant.
if we do this
#interface Class_B : Class_A
mean we are inheriting the Class_A into Class_B, in Class_B we can access all the variables of class_A.
if we are doing this
#import ....
#class Class_A
#interface Class_B
here we saying that we are using the Class_A in our program, but if we want to use the Class_A
variables in Class_B we have to #import Class_A in .m file(make a object and use it's function and variables).