- (void)sortMyArrayAndSave {
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
sortDescriptorWithKey:#"somekeydescriptor"
ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
_myarray = [[_myarray
sortedArrayUsingDescriptors:sortDescriptors] mutableCopy];
[NSKeyedArchiver archiveRootObject:_myarray
toFile:[self returnFilePathForType:#"myArray"]];
}
Can I safely assume that _myarray will be saved after the sort?
Yes, methods are executed in order on the same thread, so there shouldn't be any issues.
Related
It appears NSSortDescriptor should be a fairly easy class to work with.
I have stored in CoreData an entity with an attribute of type NSDate appropriately named #"date". I am attempting to apply a sort descriptor to a NSFetchRequest and it doesn't appear to be returning the results I had hoped for.
The result I am hoping for is to simply arrange the dates in chronological order, and instead they are returned in the order for which they were added to CoreData.
Perhaps you can offer guidance?
Is the parameter 'ascending' what controls the sort?
Some Code:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Data" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entityDesc];
[fetchRequest setFetchBatchSize:10];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
Separate sort routines (functions or blocks) look like overkill to me. I am routinely sorting Core Data entities by date attribtues just with the sort descriptor method you show in your code. It works perfectly every time.
Clearly, there must be some other mistake.
Check if the type is set correcly in your managed object model editor, and in the class file (Data.h, in your case).
Also, check if you are not manipulating this attribute so that the creation order ensues.
Also, make sure you are not mixing up this attribute with another attribute of type NSDate.
Here is more information on NSSortDescriptors
Or if you want to sort an array of dates after getting them for coreDate:
//This is how I sort an array of dates.
NSArray *sortedDateArray = [dateArray sortedArrayUsingFunction:dateSort context:NULL];
// This is a sorting function
int dateSort(id date1, id date2, void *context)
{
return [date1 compare:date2];
}
Here is code straight from apple for sorting integers (just modify to sort dates):NSComparator
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([obj1 integerValue] < [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
Add timestamp - String type field in CoreData entity
creationDate
during insertion of the record
NSManagedObject *newCredetial = [NSEntityDescription insertNewObjectForEntityForName:#"Name" inManagedObjectContext:context];[newCredetial setValue:[self getDate] forKey:#"creationDate"];
date function
- (NSString *)getDate{
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"ddMMyyyyhhmmssss";
return [formatter stringFromDate:date];}
and Use Short Description during Fetching module
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest1 = [[NSFetchRequest alloc] initWithEntityName:#"Name"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"creationDate" ascending:NO];
[fetchRequest1 setSortDescriptors:#[sortDescriptor]];
arrNameInfo = [[managedObjectContext executeFetchRequest:fetchRequest1 error:nil] mutableCopy];
just change samle ""date to Date
like in
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"date" ascending:YES];
change to
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"Date" ascending:YES];
and it works perfectly
I am sorting an NSMutableArray as follows:
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:str_key ascending:bool_asc_desc] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [ads_printers_array sortedArrayUsingDescriptors:sortDescriptors];
The problem is that this is case sensitive, and I would like to make it case insensitive. How can I do that? I tried reading the docs and found something like this:
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:str_key ascending:bool_asc_desc selector: #selector(caseInsensitiveCompare)] autorelease];
However, I have no idea what I should be putting in the selector argument. Thanks!
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:str_key
ascending:YES selector:#selector(caseInsensitiveCompare:)];
ads_printers_array = [ads_printers_array sortedArrayUsingDescriptors:[NSArray
arrayWithObject:sortDescriptor]];
For Swift, do the following:
let sortDescriptor = NSSortDescriptor(key: sortDescriptorKey, ascending: true, selector: #selector(NSString.caseInsensitiveCompare(_:)))
My object has a private NSMutableArray items. I am using the following code to sort the objects in items in size order:
-(void)sortItems{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"size" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [items sortedArrayUsingDescriptors:sortDescriptors];
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
[self setItems:newArray];
[sortDescriptor release];
}
Obviously this is a memory leak here, because every time I call sortItems, I am allocing new memory and assigning items to point to it. I've tried releasing the old memory as follows:
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
NSMutableArray* oldArray = [self items];
[self setItems:newArray];
[oldArray release];
But that gives an EXC_BAD_ACCESS error. I've read up on memory handling in objC, and I'm convinced I'm doing something fundamentally wrong here.
Any help would be greatly appreciated!
You're leaking the new array, not the old one:
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
[self setItems:newArray];
[sortDescriptor release];
[newArray release]; // <-- add this
The fundamental rule is that you must release anything that you have allocated, and you normally shouldn't care about keeping things retained for anyone (i.e. [self setItems:]), those who need something retained will do it themselves.
I would also recommend making self.items a mutable array, and using [self.items sortUsingDescriptors:sortDescriptor to sort inplace without creating a copy.
Is there a reason why you cannot release the newArray in your first example?
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"size" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [items sortedArrayUsingDescriptors:sortDescriptors];
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
[self setItems:newArray];
[newArray release];
[sortDescriptor release];
How to sort NSMutable array in ascending order. Can any one help me out this.
You haven't said what's in your array, but if it's something that responds to -compare: then you can use
[myArray sortUsingSelector:#selector(compare):];
Here is a way to sort an array of object
NSSortDescriptor * descFirstname = [[NSSortDescriptor alloc] initWithKey:#"firstname" ascending:YES];
NSSortDescriptor * descLastname = [[NSSortDescriptor alloc] initWithKey:#"lastname" ascending:YES];
[myArrayOfPerson sortUsingDescriptors:[NSArray arrayWithObjects:descLastname,descFirstname, nil]];
[descFirstname release];
[descLastname release];
Yes, you can use a NSSortDescriptor, have a look at Sort Descriptor Programming Topics.
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:nil
ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [sortValuesArray sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"sortedArray%#",sortedArray);
sortValuesArray is the array that you want to sort.
I have an NSMutableArray full of NSDictionary objects. Like so
NSMutableArray *names = [[NSMutableArray alloc] init];
for (NSString *string in pathsArray) {
NSString *path = [NSString stringWithFormat:#"/usr/etc/%#",string];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:string,#"name",path,#"path",nil];
}
pathsArray is not sortable, so I'm stuck with the order of objects inside of it. I would like to sort the names array in alphabetical order of the objects for the key: #"name" in the dictionary. Can this be done easily or will it take several levels of enumeration?
EDIT: I Found the answer on SO in this question: Sort NSMutableArray
NSSortDescriptor class.
NSSortDescriptor *sortName = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
[names sortUsingDescriptors:[NSArray arrayWithObject:sortName]];
[sortName release];
Anyone care to get some free answer points?
Try something like this:
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"name"
ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [names sortedArrayUsingDescriptors:sortDescriptors];
// names : the same name of the array you provided in your question.