Skip to content

Commit

Permalink
Adding missing descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
mattt committed Apr 13, 2014
1 parent 80f9293 commit ec3dde0
Show file tree
Hide file tree
Showing 45 changed files with 157 additions and 198 deletions.
2 changes: 1 addition & 1 deletion 2012-07-07-nsindexset.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
layout: post
title: NSIndexSet

ref: "https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSSet_Class/Reference/Reference.html"
framework: Foundation
rating: 7.8
description: "NSIndexSet (and its mutable counterpart, NSMutableIndexSet) is a sorted collection of unique unsigned integers. Think of it like an NSRange that supports non-contiguous series. It has wicked fast operations for finding indexes in ranges or set intersections, and comes with all of the convenience methods you'd expect in a Foundation collection class."
---

`NSIndexSet` (and its mutable counterpart, `NSMutableIndexSet`) is a sorted collection of unique unsigned integers. Think of it like an `NSRange` that supports non-contiguous series. It has wicked fast operations for finding indexes in ranges or set intersections, and comes with all of the convenience methods you'd expect in a Foundation collection class.
Expand Down
6 changes: 3 additions & 3 deletions 2012-07-14-nscache.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
layout: post
title: NSCache

ref: "https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSCache_Class/Reference/Reference.html"
framework: Foundation
rating: 7.5
description: "Poor NSCache, always being overshadowed by NSMutableDictionary. It's as if no one knew how it provides all of that garbage collection behavior that developers take great pains to re-implement themselves."
---

Poor `NSCache`, always being overshadowed by `NSMutableDictionary`. It's as if no one knew how it provides all of that garbage collection behavior that developers take great pains to re-implement themselves.

That's right: `NSCache` is basically just an `NSMutableDictionary` that automatically evicts objects in order to free up space in memory as needed. No need to respond to memory warnings or contrive a cache-clearing timer mechanism. The only other difference is that keys aren't copied as they are in an `NSMutableDictionary`, which is actually to its advantage (no need for keys to conform to `<NSCopying>`).
That's right: `NSCache` is basically just an `NSMutableDictionary` that automatically evicts objects in order to free up space in memory as needed. No need to respond to memory warnings or contrive a cache-clearing timer mechanism. The only other difference is that keys aren't copied as they are in an `NSMutableDictionary`, which is actually to its advantage (no need for keys to conform to `<NSCopying>`).

If developers only knew...

Expand All @@ -23,7 +23,7 @@ Take `setObject:forKey:cost:`, for example. It's the same `setObject:forKey:` me
Alright, so far so good...

> However, this eviction process is not in a guaranteed order. As a consequence, if you try to manipulate the cost values to achieve some specific behavior, the consequences could be detrimental to your program.
> However, this eviction process is not in a guaranteed order. As a consequence, if you try to manipulate the cost values to achieve some specific behavior, the consequences could be detrimental to your program.
Huh? So what's the point, then?

Expand Down
18 changes: 9 additions & 9 deletions 2012-07-24-nssortdescriptor.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
layout: post
title: NSSortDescriptor

ref: "https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSSortDescriptor_Class/Reference/Reference.html"
framework: Foundation
rating: 8.4
description: "Sorting: it's the mainstay of Computer Science 101 exams and whiteboarding interview questions. But when was the last time you actually needed to know how to implement Quicksort yourself?"
---

Sorting: it's the mainstay of Computer Science 101 exams and whiteboarding interview questions. But when was the last time you actually needed to know how to implement Quicksort yourself?
Sorting: it's the mainstay of Computer Science 101 exams and whiteboarding interview questions. But when was the last time you actually needed to know how to implement Quicksort yourself?

When making apps, sorting is just something you can assume to be fast, and utility is a function of convenience and clarity of intention. And when it comes to that, you'd be hard-pressed to find a better implementation than Foundation's `NSSortDescriptor`.

Expand All @@ -18,13 +18,13 @@ When making apps, sorting is just something you can assume to be fast, and utili
> - `key`: for a given collection, the key for the corresponding value to be sorted on for each object in the collection.
> - `ascending`: a boolean specifying whether the collection should be sorted in ascending (`YES`) or descending (`NO`) order.
There is an optional third parameter that relates to how the sorted values are compared to one another. By default, this is a simple equality check, but this behavior can be changed by passing either a `selector` (`SEL`) or `comparator` (`NSComparator`).
There is an optional third parameter that relates to how the sorted values are compared to one another. By default, this is a simple equality check, but this behavior can be changed by passing either a `selector` (`SEL`) or `comparator` (`NSComparator`).

> Any time you're sorting user-facing strings, be sure to pass the selector `localizedStandardCompare:`, which will sort according to the language rules of the current locale (locales may differ on ordering of case, diacritics, and so forth).
Collection classes like `NSArray` and `NSSet` have methods to return sorted arrays of the objects that take an array of `sortDescriptors`. Sort descriptors are applied in order, so that if two elements happen to be tied for a particular sorting criteria, the tie is broken by any subsequent descriptors.

To put that into more practical terms, consider a `Person` class with properties for `firstName` & `lastName` of type `NSString *`, and `age`, which is an `NSUInteger`.
To put that into more practical terms, consider a `Person` class with properties for `firstName` & `lastName` of type `NSString *`, and `age`, which is an `NSUInteger`.

~~~{objective-c}
@interface Person : NSObject
Expand Down Expand Up @@ -95,13 +95,13 @@ NSMutableArray *people = [NSMutableArray array];
[people addObject:person];
}];
NSSortDescriptor *firstNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"firstName"
ascending:YES
NSSortDescriptor *firstNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"firstName"
ascending:YES
selector:@selector(localizedStandardCompare:)];
NSSortDescriptor *lastNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"lastName"
ascending:YES
NSSortDescriptor *lastNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"lastName"
ascending:YES
selector:@selector(localizedStandardCompare:)];
NSSortDescriptor *ageSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"age"
NSSortDescriptor *ageSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"age"
ascending:NO];
NSLog(@"By age: %@", [people sortedArrayUsingDescriptors:@[ageSortDescriptor]]);
Expand Down
4 changes: 2 additions & 2 deletions 2012-07-31-nsdatecomponents.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
layout: post
title: NSDateComponents

ref: "https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateComponents_Class/Reference/Reference.html"
framework: Foundation
rating: 6.9
description: "NSDateComponents serves an important role in Foundation's date and time APIs. By itself, it's nothing impressive—just a container for information about a date (its month, year, day of month, week of year, or whether that month is a leap month). However, combined with NSCalendar, NSDateComponents becomes a remarkably convenient interchange format for calendar calculations."
---

`NSDateComponents` serves an important role in Foundation's date and time APIs. By itself, it's nothing impressive—just a container for information about a date (its month, year, day of month, week of year, or whether that month is a leap month). However, combined with `NSCalendar`, `NSDateComponents` becomes a remarkably convenient interchange format for calendar calculations.
Expand Down Expand Up @@ -63,7 +63,7 @@ Perhaps the most powerful feature of `NSDateComponents`, however, is the ability

~~~{objective-c}
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:1987];
[components setMonth:3];
Expand Down
15 changes: 7 additions & 8 deletions 2012-08-13-nsincrementalstore.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
---
layout: post
title: NSIncrementalStore

ref: "https://developer.apple.com/library/mac/#documentation/CoreData/Reference/NSIncrementalStore_Class/Reference/NSIncrementalStore.html"
framework: Foundation
rating: 9.5
published: true
description: Even for a blog dedicated to obscure APIs, <tt>NSIncrementalStore</tt> sets a new standard. It was introduced in iOS 5, with no more fanfare than the requisite entry in the SDK changelog. Ironically, it is arguably the most important thing to come out of iOS 5, which will completely change the way we build apps from here on out.
---

Even for a blog dedicated to obscure APIs, `NSIncrementalStore` brings a new meaning to the word "obscure".
Even for a blog dedicated to obscure APIs, `NSIncrementalStore` brings a new meaning to the word "obscure".

It was introduced in iOS 5, with no more fanfare than the requisite entry in the SDK changelog.

Expand All @@ -23,7 +22,7 @@ And yet, `NSIncrementalStore` is arguably the most important thing to come out o

`NSIncrementalStore` is an abstract subclass of `NSPersistentStore` designed to "create persistent stores which load and save data incrementally, allowing for the management of large and/or shared datasets". And while that may not sound like much, consider that nearly all of the database adapters we rely on load incrementally from large, shared data stores. What we have here is a goddamned miracle.

For those of you not as well-versed in Core Data, here's some background:
For those of you not as well-versed in Core Data, here's some background:

[Core Data](http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/cdProgrammingGuide.html) is Apple's framework for object relational mapping. It's used in at least half of all of the first-party apps on Mac and iOS, as well as thousands of other third-party apps. Core Data is complex, but that's because it solves complex problems, covering a decades-worth of one-offs and edge cases.

Expand Down Expand Up @@ -64,7 +63,7 @@ NSMutableDictionary *mutableMetadata = [NSMutableDictionary dictionary];

### `-executeRequest:withContext:error:`

Here's where things get interesting, from an implementation standpoint. (And where it all goes to hell, from an API design standpoint)
Here's where things get interesting, from an implementation standpoint. (And where it all goes to hell, from an API design standpoint)

`executeRequest:withContext:error:` passes an `NSPersistentStoreRequest`, an `NSManagedObjectContext` and an `NSError` pointer.

Expand All @@ -79,26 +78,26 @@ This method requires very specific and very different return values depending on
> **Return**: `NSArray` of objects matching request
- Result Type: `NSCountResultType`

> **Return**: <del><tt>NSNumber</tt></del><ins><tt>NSArray</tt> containing one <tt>NSNumber</tt> of count of objects matching request</ins>
#### Request Type: `NSSaveRequestType`

> **Return**: Empty `NSArray`
So, one method to do all read _and_ write operations with a persistence backend. At least all of the heavy lifting goes to the same place, right?

### `-newValuesForObjectWithID:withContext:error:`

This method is called when an object faults, or has its values refreshed by the managed object context.
This method is called when an object faults, or has its values refreshed by the managed object context.

It returns an `NSIncrementalStoreNode`, which is a container for the ID and current values for a particular managed object. The node should include all of the attributes, as well as the managed object IDs of any to-one relationships. There is also a `version` property of the node that can be used to determine the current state of an object, but this may not be applicable to all storage implementations.

If an object with the specified `objectID` cannot be found, this method should return `nil`.

### `-newValueForRelationship:forObjectWithID: withContext:error:`

This one is called when a relationship needs to be refreshed, either from a fault or by the managed object context.
This one is called when a relationship needs to be refreshed, either from a fault or by the managed object context.

Unlike the previous method, the return value will be just the current value for a single relationship. The expected return type depends on the nature of the relationship:

Expand Down
15 changes: 7 additions & 8 deletions 2012-08-27-cfbag.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
---
layout: post
title: CFBag

ref: "https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFMutableBagRef/Reference/reference.html"
framework: CoreFoundation
rating: 7.2
published: true
description: In the pantheon of collection data types in computer science, bag doesn't really have the same clout as lists, sets, associative arrays, trees, graphs, or priority queues. In fact, it's pretty obscure. You've probably never heard of it.
description: "In the pantheon of collection data types in computer science, bag doesn't really have the same clout as lists, sets, associative arrays, trees, graphs, or priority queues. In fact, it's pretty obscure. You've probably never heard of it."
---

Objective-C is a language caught between two worlds.
Objective-C is a language caught between two worlds.

On one side, it follows the thoughtful, object-oriented philosophy of [Smalltalk](http://en.wikipedia.org/wiki/Smalltalk), which brings ideas like message sending and named parameters. On the other, are the inescapable vestiges of <a href="http://en.wikipedia.org/wiki/C_(programming_language)">C</a>, which brings it power and a dash of chaos.

Expand Down Expand Up @@ -86,7 +85,7 @@ However, toll-free bridging is the exception when it comes to collection classes
</tbody>
<tfoot>
<tr>
<td colspan="3"><sup>*</sup> Indicates Mutable Counterpart</td>
<td colspan="3"><sup>*</sup> Indicates Mutable Counterpart</td>
</tr>
</tfoot>
</table>
Expand All @@ -95,7 +94,7 @@ Take a look at the second row, with `NSCountedSet` and `CFBag`. Notice that unli

## Bags, in the Abstract

In the <a href="http://en.wikipedia.org/wiki/Collection_(abstract_data_type)">pantheon of collection data types</a> in computer science, bag doesn't really have the same clout as lists, sets, associative arrays, trees, graphs, or priority queues.
In the <a href="http://en.wikipedia.org/wiki/Collection_(abstract_data_type)">pantheon of collection data types</a> in computer science, bag doesn't really have the same clout as lists, sets, associative arrays, trees, graphs, or priority queues.

In fact, it's pretty obscure. You've probably never heard of it.

Expand All @@ -105,7 +104,7 @@ Its practical applications are... limited, but you'll know one when it comes up.

## Working with `CFMutableBag`

As an implementation of the bag data type, `CFBag` and its mutable counterpart, `CFMutableBag`, are pretty slick.
As an implementation of the bag data type, `CFBag` and its mutable counterpart, `CFMutableBag`, are pretty slick.

Although it lacks the object-oriented convenience of `NSCountedSet`, it makes up for it with a number of ways to customize its behavior. When `CFBag` is created, it can be initialized with a number of callbacks, defined by the `CFBagCallBacks` struct, which specify the way values are inserted, removed, and compared:

Expand All @@ -127,14 +126,14 @@ typedef struct CFBagCallBacks CFBagCallBacks;
- `equal`: callback used to compare values in the collection for equality
- `hash`: callback used to compute hash codes for values in the collection

For example, if you were implementing a vote tallying application, you could specify a normalizing function for `retain` to ensure that votes for mixed-case or misspelled names went to the right candidate, or ensure that the "correct" candidate is shown to be the winner when all the votes are in, with `equal` callback.
For example, if you were implementing a vote tallying application, you could specify a normalizing function for `retain` to ensure that votes for mixed-case or misspelled names went to the right candidate, or ensure that the "correct" candidate is shown to be the winner when all the votes are in, with `equal` callback.

`CFMutableBag` also has `CFBagApplyFunction`, which has the ability to transform values over the collection, like if you wanted to smooth out vote counts, or something like that.

So in closing, if you need to rig an election, `CFBag` is your best bet.

---

But seriously, `CFBag`, useful in its own right, serves as a reminder of the hidden gems to be found within the standard frameworks and libraries--indeed what is at the very heart of being an NSHipster.
But seriously, `CFBag`, useful in its own right, serves as a reminder of the hidden gems to be found within the standard frameworks and libraries--indeed what is at the very heart of being an NSHipster.

Also, `CFBinaryHeap`? `NSPointerFunctions`? `NSMapTable`? Surely, you'll be seeing more of these in future editions.
Loading

0 comments on commit ec3dde0

Please sign in to comment.