EXC_BAD_ACCESS with sortUsingComparator

I understand what the EXC_BAD_ACCESS error EXC_BAD_ACCESS in general, but I am puzzled by what happens in my case.

I have my own class that has the NSComparator property sortWithThisComparator . If this property is set by the user when I insert the element into the properties array of the items instance class, I use a comparator to determine the location of the insert:

 - (void) insertItem:(id<NSCoding, CKArchivingItem>) item { if (arrayObjectClassString && ![item isKindOfClass:NSClassFromString(arrayObjectClassString)]) { [NSException raise:@"YOU MADE A MISTAKE" format:@"you tried to insert a %@ but I can only accept %@", [item class], arrayObjectClassString]; } else { if (!sortWithThisComparator) { [self.items addObject:item]; } else { NSInteger newItemIndex = [self.items indexOfObject:item inSortedRange:NSMakeRange(0, [self.items count]) options:NSBinarySearchingFirstEqual usingComparator:sortWithThisComparator]; if (newItemIndex >= [self.items count]) { [self.items addObject:items]; } else { [self.items insertObject:item atIndex:newItemIndex]; } } } } 

Everything works fine when I do not install the comparator, but when I use the comparator, I get a bad access error:

 typedef NSComparisonResult (^NSComparator)(id obj1, id obj2); ... [[CKGenericSingletonSubclass sharedManager] setSortWithThisComparator: ^NSComparisonResult(CKGeneralizedItemSubclass *i1, CKGeneralizedItemSubclass *i2) { NSLog(@"we are inside"); NSLog(@"here is the item 1 %@", i1); NSLog(@"we are comparing this float %f to thisf loat %f", i1.gradeSchoolAverage, i2.gradeSchoolAverage); if (i1.gradeSchoolAverage < i2.gradeSchoolAverage) { return NSOrderedAscending; } else if (i1.gradeSchoolAverage == i2.gradeSchoolAverage) { return NSOrderedSame; } else { return NSOrderedDescending; } }]; 

I get a bad access stream in the second line of the comparator, which simply registers one of the parameters passed through NSComparator. However, the instances of the class that I pass to insertItem are available elsewhere without this problem, so I know that they were created correctly and transferred correctly otherwise, since I can insert them into the items property without a comparator. What am I missing here?


Additional Information. I save NSComparator as

 @property (strong, atomic) NSComparator sortWithThisComparator; 
+8
sorting objective-c nsarray exc-bad-access
source share
2 answers

In fact, I can make some assumptions according to the codes you specify.

For the first block, I think self.items is a mutable array. Also in the insertItem: function, when sortWithThisComparator not equal to zero, a new object will be inserted after the sorting process receives an index.

Since you have poor access to threading issues, I think you didn’t take very good care of having so many threads in your codes.

Here are some suggestions:

  • NSMutableArray is not thread safe: I assume you put self.items working in an asynchronous thread. If I am right about this, remember every time you would like to edit self.items, there is NSLock to protect it.

Example:

 - (void)addItem:(id)item { dispatch_async(self.queue, ^{ [threadLock lock]; [self.items addObject:item]; [threadLock unlock]; } } 
  • Another sort is based on a mutable array: I think this is dangerous since a mutable array is not thread safe.

Let's look at this line:

 NSInteger newItemIndex = [self.items indexOfObject:item inSortedRange:NSMakeRange(0, [self.items count]) options:NSBinarySearchingFirstEqual usingComparator:sortWithThisComparator]; 

In my opinion, I will first make a copy of the array and set the parameters using NSBinarySearchingInsertionIndex :

 NSArray *array = [self.items copy]; NSInteger newItemIndex = [array indexOfObject:item inSortedRange:NSMakeRange(0, [array count]) options:NSBinarySearchingInsertionIndex usingComparator:sortWithThisComparator]; 
  • In addition, I found that self.items.count can be Zero , and you do NSMakeRange(0, self.items.count) . Probably also slightly change the state in the insertItem: function
 if (!sortWithThisComparator || self.items.count == 0) {} 

Here are some thoughts that I have in this movement. I will add one more time when I get ideas for other features.

+1
source share

I think the problem is using sortWithThisComparator , which you use as a variable, not as a property. Try replacing sortWithThisComparator with self.sortWithThisComparator Let me self.sortWithThisComparator if this helps

0
source share

All Articles