Is there anything like a generic list in Cocoa / Objective-C?

28,622

Solution 1

Wanting this in a Cocoa app is often a sign of a weak design.

NSArray is immutable, so it will not "take a pointer to any object" and presumably already contains the correct objects when handed to you. What I assume you're more worried about is an NSMutableArray where you think other parts of your code might add the wrong sort of object. But have a look at Cocoa itself; it's incredibly rare to expose a mutable array as part of a class's design.

Instead, you generally expose an NSArray and a couple of methods for modifying that array. Something along the lines of:

@class Foo : NSObject
- (NSArray *)bars;
- (void)addBar:(Bar *)bar;
- (void)removeBar:(Bar *)bar;
@end

This generally stops wrong objects being inserted simply by having a compiler warning, and then of course you can add assertions within -addBar: and -removeBar: if you wish too.

Solution 2

Objective-C doesn't support generic programming. You could always use Objective-C++ and an STL list.

Solution 3

Generic NSArrays can be realized by subclassing NSArray, and redefining all provided methods with more restrictive ones. For example,

- (id)objectAtIndex:(NSUInteger)index

would have to be redefined in

@interface NSStringArray : NSArray

as

- (NSString *)objectAtIndex:(NSUInteger)index

for an NSArray to contain only NSStrings.

The created subclass can be used as a drop-in replacement and brings many useful features: compiler warnings, property access, better code creation and -completion in Xcode. All these are compile-time features, there is no need to redefine the actual implementation - NSArray's methods can still be used.

It's possible to automate this and boil it down to only two statements, which brings it close to languages that support generics. I've created an automation with WMGenericCollection, where templates are provided as C Preprocessor Macros.

After importing the header file containing the macro, you can create a generic NSArray with two statements: one for the interface and one for the implementation. You only need to provide the data type you want to store and names for your subclasses. WMGenericCollection provides such templates for NSArray, NSDictionary and NSSet, as well as their mutable counterparts.

Share:
28,622
TalkingCode
Author by

TalkingCode

Updated on September 05, 2020

Comments

  • TalkingCode
    TalkingCode over 3 years

    What I really like in C# are generic lists. A list that can contain only one type of objects. Is there something like a generic list in Cocoa/Objective-C? As far I only know NSArray who will take a pointer to any object.

  • Mike Abdullah
    Mike Abdullah about 15 years
    Also, if you need more advanced operations, read up on -mutableArrayValueForKey:
  • Paul Delhanty
    Paul Delhanty almost 12 years
    -1 Strongly Disagree - denying that adding C# generics to Objective C would
  • Paul Delhanty
    Paul Delhanty almost 12 years
    ... be a definite improvement. Language support for strong typing and dynamic typing are complementary techniques. Prediction: Objective C will implement C# style generics one day.
  • Chris Hatton
    Chris Hatton almost 12 years
    Generics are not a weak design, wanting them is not a sign of weak design. They just happen not to apply to Objective-C. The rest of your answer is helpful, however the opening statement is completely incorrect and misleading.
  • Mike Abdullah
    Mike Abdullah almost 12 years
    Well since this was a Cocoa question, my answer was specific to Cocoa!
  • mecabpazzo95
    mecabpazzo95 over 11 years
    Generic lists are a fine idea, and a strong design. Heterogeneous lists on the other hand, are a terrible idea.
  • Daniel Ryan
    Daniel Ryan about 11 years
    I wish Objective C had generics, it would help understand others peoples code so much easier. It's a time saver. I don't see it as a weak design at all.
  • Andrew Barber
    Andrew Barber about 11 years
    Thanks for posting your answer! Please be sure to read the FAQ on Self-Promotion carefully. Also note that it is required that you post a disclaimer every time you link to your own site/product.
  • w-m
    w-m about 11 years
    Thanks for pointing that out. I was quite unsure how to do this or whether it is considered too spammy. Right now I am busy but I will rework the answers according to the guidelines in a couple of hours.
  • Andrew Barber
    Andrew Barber about 11 years
    Excellent! Your last two answers are decent, because they seem to address the question, you've included some good information (not just "see this project here" and a feature list). Just add the disclosure, and they are just fine. thanks again! Oh, also; just FYI; do be careful about posting exact copies of answers; These seem to be good enough for their questions, but be sure to try to tailor answers to the question specifically.
  • David Jeske
    David Jeske almost 11 years
    Obj-C and C#/Java folks are talking aside each-other on this issue. Java-style generics, which force collections to contain only objects derived from a specific base class are a bad idea in Objective-C, because Obj-C is a language based on protocol (interface) compatibility. (Sometimes called duck typing, because if it quacks like a duck it's a duck) HOWEVER, Obj-C could benefit from parametric protocol conformance. With this collections could be declared to allow only elements conforming to specific protocols. Helping turn runtime errors into compile time errors.
  • w-m
    w-m almost 11 years
    "In fact, looking at actual types is a very very bad practice in Obj-C and in highly discouraged". Could you expand on that? All the standard data objects are implemented with inheritance, not protocols. Take for Example NSDecimalNumber : NSNumber : NSValue : NSObject. Or, NSString which doesn't provide a protocol either. Thus, of the two compile-time options, isKindOfClass: can be used while conformsToProtocol: can't. How is that bad practice?
  • Mark Amery
    Mark Amery over 10 years
    So your take on this is "This is unnecessary and wanting it is a sign of weak design. Why would you need it when you can do it yourself by defining a cumbersome extra class instead whose whole purpose is to simulate a generic array (for one particular type only) in many, many times as many lines of code?" That seems incredibly asinine.
  • Mike Abdullah
    Mike Abdullah over 10 years
    I'm not suggesting people effectively recreate large chunks of the NS(Mutable)Array API on a regular basis. There's generally only a few methods needed, and this tends to be part of some wider class for holding other properties too
  • drlobo
    drlobo over 10 years
    I thought List have performance improvements in some scenarios where inserting items into the middle of the collection
  • Mike Abdullah
    Mike Abdullah over 10 years
    @drlobo sounds like you're thinking of a Linked List? If so, that has basically nothing to do with the topic at hand.