Daily Archives: November 4, 2010

How to Break Into a Mac (And Prevent It from Happening to You) [Passwords]

We recently went through a few ways to break into a Windows PC without the password, and it turns out it’s just as easy to break into a Mac too. Here’s how to do it and keep yourself protected. More »







Two People Cooperate Intuitively; Larger Groups Need to Make a Conscious Effort to Communicate [Communication]

If you’re used to working closely with a partner, it’s easy to forget how complexity in working relationships grows when the size of your group grows. Next time it seems like a co-worker just isn’t getting it, consider this piece of research. More »







An Introduction to Categories (Part 1 of 2)

photoHave you ever wished that you could add one, or a couple, additional functions to an Objective-C core class?
Well Apple has thought of this, and they provide a way without extended the class! The way to do this is called a category. A category is a way to enhance an existing class, by adding additional functions to it. The difference between this and extending a class is that when you extend a class, you can add additional functions, as well as variables. In a category, you can only add additional functions. The benefit of a category though is that you don’t have to use the extended class to get the benefits of the added additional functions. All you have to do is include the header file of the category, and the additional functions of that class are available to you.

NSExpression

The relatively new NSExpression class is incredibly powerful, yet not really used very often. Part of that is that it’s not very well documented. Although the API documentation for NSExpression is fairly well detailed, the listed “companion guide” (Introduction to Predicates Programming) has very little information about how to actually use NSExpression.

NSExpression deserves to be better documented, because it brings to predicate programming (including Core Data), a lot of features from the relational database world that people often complain are missing, like unioning, intersecting, and subtracting resultsets and performing aggregate operations without loading managed objects or faults into memory.

The aggregates functionality is especially important on iOS given the limited memory on most iOS devices. If you’ve got a large dataset, and you want to get a count of objects, or calculate an average or sum for one of the attributes, you really don’t want to have to pull the entire dataset into memory. Even if they’re just faults, they’re going to eat up memory you don’t need to use because the underlying SQLite persistent store can figure that stuff out without the object overhead.

I don’t have time to do a full NSExpression tutorial, but I thought it at least worth posting a category on NSManagedObject that lets you take advantage of some of its more useful features.

With this category, to get a sum of the attribute bar on entity Foo, you would do this:

NSNumber *fooSum = [Foo aggregateOperation:@"sum:" onAttribute:@"bar" withPredicate:nil inManagedObjectContext:context];

This will calculate it for you using the database features, NOT by loading all the managed objects into memory. Much more memory and processor efficient than doing it manually.

Cheers. Category follows:

Header File:

@interface NSManagedObject(MCAggregate)
+(NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inManagedObjectContext:(NSManagedObjectContext *)context
@end

Implementation File:

+(NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inManagedObjectContext:(NSManagedObjectContext *)context
{
NSExpression *ex = [NSExpression expressionForFunction:function
arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:attributeName]]
]
;

NSExpressionDescription *ed = [[NSExpressionDescription alloc] init];
[ed setName:@"result"];
[ed setExpression:ex];
[ed setExpressionResultType:NSInteger64AttributeType];

NSArray *properties = [NSArray arrayWithObject:ed];
[ed release];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];

if (predicate != nil)
[request setPredicate:predicate];

NSEntityDescription *entity = [NSEntityDescription entityForName:[self className]
inManagedObjectContext:context
]
;
[request setEntity:entity];

NSArray *results = [context executeFetchRequest:request error:nil];
NSDictionary *resultsDictionary = [results objectAtIndex:0];
NSNumber *resultValue = [resultsDictionary objectForKey:@"result"];
return resultValue;

}

@end
©2008-2010 Jeff LaMarche.
iphonedevelopment.blogspot.com
WP Like Button Plugin by Free WordPress Templates