1

I think I've seen this done, but I can't find documentation on it because I don't think I know the correct terms. I need to know how to write a special class that's only for use inside one other class, and therefore can be entirely written inside the other class's implementation.

Basically I need a specialized NSMutableArray that can do three extra things:

  • remove the most recent item once it's asked for
  • store that item in a last_most_recent_item variable
  • track whether or not a new item has been added
  • if a new item hasn't been added, and the last object in the array is asked for, return the last_most_recent_item instead of the actual last item

But, and here's the thing, I only need this SpecialNSArray inside of one class. So I'd like to put the declaration and implementation inside that class, instead of in separate files. I believe I've seen that done. Does anyone know what that's called, and how I could do it?

Le Mot Juiced
  • 3,761
  • 1
  • 26
  • 46
  • I believe you need to create a private interface in the implementation file. – Popeye Jul 18 '12 at 17:03
  • 2
    This kind of thing is probably better handled through composition rather than subclassing (or even categories, which are an excellent tool usually). Look at NSAttributedString for an example of this. NSAttributeString is not a subclass of NSString. It has-a NSString. You probably want the same kind of relationship. – Rob Napier Jul 18 '12 at 17:25
  • With composition, do you have to pass through (recreate) all of the accessors (or at least the ones you are using) of the component classes, or is there another way to do that? – Jim Jul 18 '12 at 17:38
  • @Jim see delegation http://swannman.github.com/scriptsaver/ – mmmmmm Jul 18 '12 at 20:22

3 Answers3

4

To do this just add the new class to the implementation file of the class you want to use it. I think this has been called a private class.

Suppose your class is MyClass and the improved array is MyArray the in MyClass.m

@interface MyArray
{


}
@end

@implementation MyArray

@end


@implementation MyClass

@end

In this case the extra methods on MyArray are only seen by the compiler if they are called from MyClass.

Note that there is nothing private in Objective C these methods on MyArray can be called at runtime from anywhere in your program it is just that these methods will raise a warning at compile time.

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
3

I think you are describing a category on NSMutableArray.

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html

YourClass.m
@interface NSMutableArray : (YourClassExtentions)
@end

@implementation NSMutableArray : (YourClassExtentions)
@end

@implementation YourClass()
@end

You could also just create the category in separate m and h files, and import.

adc
  • 439
  • 3
  • 8
  • A category can be added anywhere including a header so is not necessarily specific to one class so is definitely not what this pattern is called.However your code does meet the requirements as the @interface and implementation of the category are in YourCLass.m – mmmmmm Jul 18 '12 at 16:59
  • 2
    A category is a clean way to do this, as adc describes. Your specification calls for some persistent attributes which are often achieved by subclassing, but, as you probably discovered, NSArray does not subclass, so that's not an option. You might consider using associated objects with your category. http://stackoverflow.com/questions/4071500/how-to-add-properties-to-nsmutablearray-via-category-extension has a good accepted answer on the topic. – Jim Jul 18 '12 at 17:16
  • @Jim the point is the question is about putting the other class in the file not wether it should be a Category - I agree that a category might be the correct implementation here but the implementation is the same as the current way the OP is doing it. – mmmmmm Jul 18 '12 at 17:28
  • Unfortunately, categories can't have their own variables, and one of the main points of this class is to add the extra variables last_most_recent_item and the one to check if a new item has been added or not. – Le Mot Juiced Jul 18 '12 at 23:40
1

You can simply put the class's @interface MyInternalClass ... and @implementation MyInternalClass ... code segments in the .m file for your "public" class. Add a @class MyInternalClass; line to the .h so that you can declare pointers to that class in your "public" class's instance variables.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151