2016-02-03 5 views
8

के साथ EXC_BAD_ACCESS मैं समझता हूं कि त्रुटि EXC_BAD_ACCESS सामान्य रूप से क्या है, लेकिन मुझे इस मामले में क्या हो रहा है इसके बारे में परेशान है।sortCsingComparator

मेरे पास एक कस्टम क्लास है जिसमें NSComparator संपत्ति sortWithThisComparator है। कि संपत्ति उपयोगकर्ता द्वारा सेट किया जाता है, जब मैं उदाहरण के वर्ग संपत्ति सरणी items में एक आइटम डालने मैं तुलनित्र का उपयोग प्रविष्टि स्थान निर्धारित करने के लिए:

- (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]; 
      } 
     } 
    } 
} 

सब कुछ ठीक काम करता है जब मैं एक तुलनित्र निर्धारित नहीं करते हैं, लेकिन मैं एक बुरा पहुँच त्रुटि मिलती है जब मैं तुलनित्र का उपयोग करते हैं:

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; 
     } 
    }]; 

मैं तुलनित्र, जो केवल मापदंडों NSComparator के माध्यम से पारित कर दिया है पेड़ों की कटाई की दूसरी पंक्ति पर बुरा पहुँच धागा मिलता है। फिर भी कक्षा उदाहरण मैं insertItem पर जा रहा हूं, इस समस्या के बिना कहीं और सुलभ है, इसलिए मुझे पता है कि उन्हें ठीक से ठीक किया गया है और अन्यथा ठीक से पारित किया गया है क्योंकि मैं उन्हें items संपत्ति के बिना तुलनात्मक रूप से ठीक कर सकता हूं। मुझे यहां क्या समझ नहीं आ रहा है?


और जानकारी। मैं NSComparator को

@property (strong, atomic) NSComparator sortWithThisComparator; 
+0

आप ब्लॉक को संपत्ति के रूप में कैसे स्टोर करते हैं? क्या आप इसे प्रश्न में जोड़ सकते हैं, अगर कोई भी सेटर कार्यान्वयन भी कर सकता है। – Alistra

+0

@Alistra मैंने एक स्पष्ट सेटटर नहीं लिखा बल्कि इस संपत्ति की संपत्ति (मजबूत, परमाणु) एनएससीओम्परेटर सॉर्ट WithThisComparator सेट करें; – sunny

उत्तर

1

असल में, मैं केवल ऊपर वर्णित कोड के अनुसार कुछ मान्यताओं को बना सकता हूं।

पहले ब्लॉक के लिए, मुझे लगता है कि self.items एक म्यूटेबल सरणी है। फ़ंक्शन insertItem: में, sortWithThisComparator एक बार शून्य नहीं है, सॉर्टिंग प्रक्रिया को इंडेक्स मिलने के बाद नई ऑब्जेक्ट डाली जाएगी।

क्योंकि आपको थ्रेड मुद्दों पर खराब पहुंच मिलती है, मुझे लगता है कि आपने अपने कोड में बहुत अच्छी तरह से थ्रेडिंग का ख्याल नहीं रखा है।

  • NSMutableArray सुरक्षित थ्रेड नहीं है:

    यहाँ कुछ सुझाव हैं मैं तुम्हें self.items एक अतुल्यकालिक सूत्र में आपरेशन कर दिया लगता है। अगर मैं इसके बारे में सही हूं, तो हर बार याद रखें कि आप self.items को संपादित करना चाहते हैं, इसकी सुरक्षा के लिए एनएसएलॉक है।

पूर्व:

- (void)addItem:(id)item { 
    dispatch_async(self.queue, ^{ 
     [threadLock lock]; 
     [self.items addObject:item]; 
     [threadLock unlock]; 
    } 
} 
  • एक और एक परिवर्तनशील सरणी के आधार पर क्रमित है: मुझे लगता है कि यह खतरनाक है भी के बाद से परिवर्तनशील सरणी सुरक्षित थ्रेड नहीं है।

की इस लाइन की एक नज़र डालते हैं:

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

मेरी राय में, मैं NSBinarySearchingInsertionIndex के साथ पहली और सेट विकल्प एक सरणी की नकल करना होगा:

NSArray *array = [self.items copy]; 
NSInteger newItemIndex = [array indexOfObject:item inSortedRange:NSMakeRange(0, [array count]) options:NSBinarySearchingInsertionIndex usingComparator:sortWithThisComparator]; 
  • इसके अलावा, मैं एक स्थिति मिली जो self.items।गिनती शून्य हो सकती है और आप NSMakeRange(0, self.items.count) बना रहे हैं। शायद भी समारोह insertItem: में हालत छोटा सा संशोधन,
if (!sortWithThisComparator || self.items.count == 0) {}

ये कुछ विचार मैं इस आंदोलन में होती है। एक बार जब मैं अन्य संभावनाओं के लिए विचार प्राप्त करता हूं तो मैं और अधिक जोड़ दूंगा।

+0

नमस्ते, अगर हम बस परिवर्तनीय संग्रह 'सॉर्टविथकंपेटर का उपयोग करना चाहते हैं: पृष्ठभूमि कतार पर जीसीडी के माध्यम से, क्या आपको लगता है कि लॉक की अभी भी आवश्यकता है? – valeCocoa

+0

@ valeCocoa हाँ, मुझे लगता है कि ज्यादातर मामलों में। जब तक आप एक समर्पित सीरियल प्रेषण कतार, या समवर्ती नियंत्रण के लिए अन्य तंत्र स्थापित नहीं करते हैं। – Allen

0

जो मुझे लगता है कि sortWithThisComparator का उपयोग करने के साथ आप एक संपत्ति के रूप में उपयोग नहीं कर रहे हैं। को self.sortWithThisComparator के साथ बदलने का प्रयास करें मुझे बताएं कि क्या यह