Objective-c KVC: Collection Accessor Patterns for To-Many Properties, how can I use this to enhance my code?
Asked Answered
B

3

6

I was reading :Collection Accessor Patterns for To-Many Properties, but I'm not sure where can I or should I use this. Can someone please point out some scenarios that I can use Collection Accessor Patterns for To-Many Properties to make my code better or make my code writing easier?

Barramunda answered 30/6, 2013 at 5:47 Comment(0)
C
3

The collection accessor patterns that you were reading about improve the way key value coding works with collections like NSArray, NSDictionary, etc. If you implement them in your own classes, your classes can be used with KVC just like the standard collection classes. For example, maybe you've got a Flight class that contains a list of Passenger. But maybe those passengers aren't stored in an NSArray, but pulled from an database or something. If you implement the following methods:

  • -countOfPassengers
  • -passengersAtIndexes:
  • -getPassengers:range:

then code using your class can use KVC to efficiently access the passenger list. For example, you might get a list of passenger frequent flyer numbers (assuming Passenger has such a property) like this:

NSArray *frequentFlyerNumbers = someFlight.passengers.frequentFlyerNumbers;

That's pretty handy stuff -- saves you from having to iterate over the collection and collect all those numbers yourself. If you weren't aware that you could do that with the standard collections like NSArray, this might seems surprising, so take a minute to absorb that part first and then consider that by implementing a few simple methods you've done the same thing for your own Flight class. It's pretty cool that this works even though the storage of the passengers is entirely internal to your class.

Now, the methods above only cover getters, but you can do the same for setters by implementing:

  • -insertPassengers:atIndexes:
  • -removePassengersAtIndexes:
  • -replacePassengersAtIndexes:withPassengers:

Now, again, your code can add and remove passengers from a flight using KVC:

[someFlight replacePassengersAtIndexes:bumpedPassengerIndexes 
                        withPassengers:passengersFromLateConnectingFlight];

There are other KVC accessors that you can implement, too, but I don't think I need to list them all for you since they're right there in the article that you linked. The point is that key value coding is useful stuff that's used in a number of places, and by implementing a small handful of methods you can make your own classes KVC compliant.

Colchicine answered 3/7, 2013 at 9:25 Comment(0)
N
0

There are some cases where it comes in really handy! Here are some self-explanatory examples.

Suppose you have an array of sales prices for the same item and want to know the average price.

NSNumber *averagePrice = [salesPrices valueForKeyPath:@"@avg.self"];

If it is more complicated this approach is still surprisingly concise and elegant. Suppose you have a transactions array of dictionaries, each with a key "object" and "price". You want the sales total for apples.

NSArray *apples = [transactions filteredArrayUsingPredicate:
  [NSPredicate predicateWithFormat:@"object = %@", @"apple"]];
NSNumber *totalApplesSales = [apples valueForKeyPath:@"@sum.price"];

Please also check out the examples given in the Key Value Coding Programming Guide. They are also very illustrative.

Neisse answered 30/6, 2013 at 8:30 Comment(1)
Not wrong, but the OP asked about collection accessor patterns while your answer seems to cover collection operators like @avg and @sum. They're not the same thing.Colchicine
S
0

To add to this. Adopting these in your class API allows your class to take advantage of the same established generic coding behaviors in Foundation collections.

One useful example would be the unordered collection. You could implement this so that all the public properties of your class are accessible as it were a dictionary. allKeys would return the property names. allValues would return the values of those properties. instanceOfYourClass[aPropertyName] would return the property aPropertyName

This would allow quick iteration and introspection. Implementation would take some effort but would make a class fit nicely into KVC and KVO and add the ability to do simple and clever things with bindings as well.

Smaze answered 3/7, 2013 at 9:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.