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).
Related
In NSArray.h I saw the interface like this
#interface NSArray<ObjectType>
What is the significance of <ObjectType>?
That is Apple using lightweight generics. The full #interface declaration in Xcode 7.3.1 looks like this:
#interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
ObjectType is a placeholder used to represent the generic argument you pass into so that the compiler knows where to reference them. This is different than using NSObject * because ObjectType is like id, it can refer to non-Objective-C pointer types such as CoreFoundation objects.
For example, if I wanted to create a class that mocks an array for only a specific class, I could do something like #interface MYArray<MyClass *>.
You could also specifically declare an array of strings as NSArray<NSString *>.
See this article on Objective-C Generics for more information.
Say I have a class Parent and the child is Child1 and Child2.
I declare Parent+ParentCategory and then I declare a method:
-(void) Redraw;
Later I want the Redraw function of Child1 to be different than the Redraw function of Child2.
Can I declare Child1+Child1Category and then override the
-(void) Redraw
Can -(void)Redraw of Child1 call the function in the parent category?
Can that be done?
What would be good approach?
I know classes can inherit each other. I know protocol can extend each other. I wonder why category doesn't?
I do not agree with the given answers:
A.: It is not true, that category's methods win against class' method. This is an implementation detail, but the behavior is not defined.
If the name of a method declared in a category is the same as a method
in the original class, or a method in another category on the same
class (or even a superclass), the behavior is undefined as to which
method implementation is used at runtime.
B.
But this does not matter. You neither define a method in a category that is defined in the class nor define a method in two clashing categories. The cit. simply does not apply to your case. It applies to something like this:
#interface A : NSObject
- (void)doSomething;
#end
#implementation A
- (void)doSomething {}
#end
#interface A (Addition)
- (void)doSomething;
#end
#implementation A (Addition)
- (void)doSomething {}
#end
If I understand you correct, you do not want to do this. You want something like that:
Base level:
#interface A : NSObject
#end
#implementation A
#end
#interface A (Addition)
- (void)doSomething;
#end
#implementation A (Addition)
- (void)doSomething {}
#end
This does not break the rule, because there is no method in the category, which is in the class.
Subclass level:
#interface B : A
#end
#implementation B
#end
#interface B (Addition)
- (void)doSomething;
#end
#implementation B (Addition)
- (void)doSomething {}
#end
There is no clash on the level of B for the same reason as there is no clash on the level of A.
Somebody might say, that there is a clash, because B inherits -doSomething from A. But this is no clash, because in this case a priority rule applies: Subclasses overwrite methods.
You can do that.
Edit:
You can check the problem simply by adding the method to the class. Would that compile? In the clashing case, it wouldn't. In your case, it would.
I will replay with a cit. from this answer:
Lets just put it this way. Don't override methods using categories, period, ever, end of answer.
The reason of this is that while it is exactly known that a category's method always win against a class method (that is, if you implement a method in a category that's already declared in the class you are extending with the category the method of the category will be called.) when you have multiple category implementing the same method which implementation takes precedence is undefined
It is not wise to use category to do this. Categories add methods to the current class. If there are multiple methods with the same name, it will replace the old one (it is NOT an override). But unfortunately it is hard to say which one is replaced. Don't do it or you may get in trouble.
And you probably can not call the method in Parent from the child category. The most proper design here is a protocol.
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.
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.