Is there anything like a generic list in Cocoa / Objective-C?
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.
TalkingCode
Updated on September 05, 2020Comments
-
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 about 15 yearsAlso, if you need more advanced operations, read up on -mutableArrayValueForKey:
-
Paul Delhanty almost 12 years-1 Strongly Disagree - denying that adding C# generics to Objective C would
-
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 almost 12 yearsGenerics 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 almost 12 yearsWell since this was a Cocoa question, my answer was specific to Cocoa!
-
mecabpazzo95 over 11 yearsGeneric lists are a fine idea, and a strong design. Heterogeneous lists on the other hand, are a terrible idea.
-
Daniel Ryan about 11 yearsI 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 about 11 yearsThanks 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 about 11 yearsThanks 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 about 11 yearsExcellent! 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 almost 11 yearsObj-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 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 over 10 yearsSo 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 over 10 yearsI'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 over 10 yearsI thought List have performance improvements in some scenarios where inserting items into the middle of the collection
-
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.