Subcategory of Category in Objective-C - objective-c

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.

Related

How to avoid different category extension define the same methods

Objective-c class can be extended by categories.
But with multi category extensions on a same class by over define a same method, the result is not defined -- As following case:
#implementation someClass (category1)
- (void)foo {}
#end
#implementation someClass (category2)
- (void)foo {}
#end
In that case, compiler even won't show any warning message. In some big project and with different people for maintenance, this kind of case is quite difficult to be addressed.
So my question is: is there any sophisticated pattern or resolution for avoiding this scenario?
For big projects, a good practice is to also add a prefix to your method names like :
- (void)nd_foo;
- (void)sp_foo;

using #property for a class I implemented

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.

Why is the protocol defined twice in Apple's sample code?

I am looking at Apple's sample code for lazy table image loading. I see that they have two lines starting with #protocol ParseOperationDelegate. Why do they do this twice? All the documentation on Objective C protocols I've looked at do not tell you to do it twice.
#class AppRecord;
#protocol ParseOperationDelegate;
//#interface ParseOperation : NSOperation <NSXMLParserDelegate>
#interface ParseOperation : NSOperation
{
#private
id <ParseOperationDelegate> delegate;
NSData *dataToParse;
NSMutableArray *workingArray;
//AppRecord *workingEntry;
//NSMutableString *workingPropertyString;
//NSArray *elementsToParse;
//BOOL storingCharacterData;
}
- (id)initWithData:(NSData *)data delegate:(id <ParseOperationDelegate>)theDelegate;
#end
#protocol ParseOperationDelegate
- (void)didFinishParsing:(NSArray *)appList;
- (void)parseErrorOccurred:(NSError *)error;
#end
The #protocol ParseOperationDelegate; line is not defining the protocol. It's a forward declaration. Basically it's saying that "a protocol called ParseOperationDelegate exists and is defined somewhere else in the code".
They do this so that the compiler will not die with an error on the line that goes id <ParseOperationDelegate> delegate;. The alternative would be to have the entire protocol definition placed before the interface definition (which personally I think would be a better solution in this case).
In such a simple case as this one I think there is little point in having the forward declaration. But you can easily imagine a more complex case where perhaps the protocol definition lives in its own header file (or in the header file for some other class). In a case like that, using a forward declaration allows you to avoid having to #import the protocol's header file into your class's header. It's a small difference, really, but it can be useful.

Do Objective-C Category names do anything?

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 ...

What is the concept of Inheritance in Objective-C?

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).