Monday, February 1, 2010

Creating an array from a set

I'm working with Core Data, and ran into the problem that I need ordered data from a result set from Core Data. the difficulty is that it's not a primary query, but from a relationship. My solution was to create a category for NSSet that allows me to create an ordered array (based on a sort criteria):

// An extension of NSSet to get a sorted array from that set.


@interface NSSet(ArrayMethods)

- (NSArray*) getSortedArray:(NSString*) primaryKey;

@end


@implementation NSSet(ArrayMethods)

- (NSArray*) getSortedArray:(NSString*) primaryKey

{

NSSortDescriptor *sortDesc =

[[NSSortDescriptor alloc] initWithKey:primaryKey

ascending:YES

selector:@selector(localizedCaseInsensitiveCompare:) ];

NSArray *descArray=[[NSArray alloc] initWithObjects:sortDesc,nil] ;

NSArray *returnValue=[[self allObjects] sortedArrayUsingDescriptors:descArray] ;

[descArray release];


return returnValue ;

}

@end


There are probably better ways to do this, and I might find a memory error in there at some point in time,(although I think I have it right).

Properties and Retain

I just found the answer to a problem that has been bedeviling me for a while, I had a crash with a deallocated object. The object was a property and I was POSITIVE that I had the proper memory management. I could workaround it with an extra retain, but I hated that solution.

I finally found an answer on Stack Overflow by Chris Hanson:


I had a property named currentWords that I was setting equal to another value:

@property (nonatomic,retain) NSArray * currentWords;


and using

currentWords=result;


The problem was that invoking a variable this way DOES not invoke the retain or other characteristics of the automatically created setter. The proper way to represent this is:


self. currentWords=result;


I'm sure for someone used to Objective-C this is obvious, but coming from C# and Java this was not an obvious error, and caused me much debugging. I had a workaround with an extra retain, but I don't want to have bogus code present, I want to solve the problem for real.