2010-12-08 5 views
4

Ich habe einige Kerndaten-Code, der Apples sample code präzise folgt (die Abrufen von Attributwerten, die eine gegebene Funktion erfüllen Beispiel). Ich verwende es, um den Maximalwert eines Feldes zu erhalten, also kann ich es erhöhen, wenn ich das nächste Objekt dieses Entitätstyps einfüge.- [NSCFNumber count]: nicht erkannte Selektor

Ich konnte den Code überhaupt nicht funktionieren, bis ich meinen Store Type von NSXMLStoreType zu NSSQLiteStoreType wechselte, dann schien plötzlich alles zu funktionieren. Das ist jedoch nicht der Fall. Mir ist aufgefallen, dass es immer denselben Wert zurückgibt, selbst wenn ich Objekte mit einem höheren Wert eingefügt habe. Aber nachdem ich beendet und wieder geöffnet habe (und somit die Daten erhalten und wieder eingelesen wurden), würde es mit den neuen Einfügungen aktualisiert werden.

Also dann fing ich an, nach jedem Einsatz zu committen und zu speichern. obwohl nach der ersten „Autosave“, erhalte ich den Fehler unten (zweimal hintereinander):

- [NSCFNumber count]: Unbekannter Selektor an Instanz gesendet 0x100506a20

Dies geschieht (zweimal in Reihen), wenn ich führe die Abrufanforderung einmal:

NSArray *objects = [context executeFetchRequest:request error:&error]; 

aktualisiert

ich ließ meinen Code über das Zombie Instrument und konnte einen lo nehmen ok am Objekt, das den Fehler bekommt. Der Anruf, der malloc ausführt, um es zuzuweisen, lautet: -[NSUserDefaults(NSUserDefaults) initWithUser:]. Da ich keine eigenen Standardeinstellungen habe, weiß ich nicht, welches Objekt das sein könnte.

Update 2

I für „Freigabe“ durch alle meine Code gesucht und aus jeder release oder autorelease kommentierte, dass der statische Analysator über nicht beschweren. Ich habe immer noch die Fehler. Ich bin sogar so weit gegangen, jeden letzten release/autorelease in meinem Code zu kommentieren und habe es immer noch. Jetzt bin ich ziemlich sicher, dass mein eigener Code nicht übermäßig freigibt.

aktualisieren 3

This post scheint das gleiche Problem zu sein, aber seine Lösung nicht sinnvoll. Er hat den Ergebnistyp von NSDictionaryResultType in NSManagedObjectResultType geändert, was zu einem falschen Ergebnis führt. Anstatt einen einzigen Wert zurückzuerhalten (den von mir gesuchten max), der jedes Objekt meiner Entitätsklasse im Kontext des verwalteten Objekts zurückgibt.

Hier sind die obersten Ebenen des Stack-Trace (wenn I es auf der Ausnahme zu brechen hat, das erste Mal).

#0 0x7fff802e00da in objc_exception_throw 
#1 0x7fff837d6110 in -[NSObject(NSObject) doesNotRecognizeSelector:] 
#2 0x7fff8374e91f in ___forwarding___ 
#3 0x7fff8374aa68 in __forwarding_prep_0___ 
#4 0x7fff801ef636 in +[_NSPredicateUtilities max:] 
#5 0x7fff800d4a22 in -[NSFunctionExpression expressionValueWithObject:context:] 
#6 0x7fff865f2e21 in -[NSMappedObjectStore executeFetchRequest:withContext:] 
#7 0x7fff865f2580 in -[NSMappedObjectStore executeRequest:withContext:] 

ich diese Frage auf zahlreiche Foren im Internet an anderer Stelle gesehen haben, aber niemand eine praktikable Lösung angeboten hat fachen Wunsch habe ich meine eigenen Der Name meiner Entität lautet Box und die Eigenschaft, die ich versuche, den Wert von "sortOrder" zu erhalten, ist ein Int 32 Attribut.

NSManagedObjectContext *context = [MyLibrary managedObjectContext]; 

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
[request setEntity:[NSEntityDescription entityForName:@"Box" 
           inManagedObjectContext:context]]; 

// Specify that the request should return dictionaries. 
[request setResultType:NSDictionaryResultType]; 

// Create an expression for the key path. 
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"sortOrder"]; 

// Create an expression to represent the function you want to apply 
NSExpression *expression = [NSExpression expressionForFunction:@"max:" 
                arguments:[NSArray arrayWithObject:keyPathExpression]]; 

// Create an expression description using the minExpression and returning a date. 
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 

// The name is the key that will be used in the dictionary for the return value. 
[expressionDescription setName:@"maxSort"]; 
[expressionDescription setExpression:expression]; 
[expressionDescription setExpressionResultType:NSInteger32AttributeType]; 

// Set the request's properties to fetch just the property represented by the expressions. 
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]]; 

// Execute the fetch. 
NSError *error; 
NSNumber *requestedValue = nil; 
NSArray *objects = [context executeFetchRequest:request error:&error]; 
NSLog(@"objects: %@", objects); 
if (objects != nil && [objects count] > 0) { 
    requestedValue = [[objects objectAtIndex:0] valueForKey:@"maxSort"]; 
} else { 
    [[NSApplication sharedApplication] presentError:error]; 
} 

[expressionDescription release]; 
[request release]; 

NSLog(@"Max Sort Order: %@", requestedValue); 
return requestedValue; 
+0

Wenn Sie sagen, dass es Apple-Code genau folgt, meinst du, es ist buchstäblich Byte für Byte identisch oder könnten Sie möglicherweise, sagen wir, eine Instanzvariable anstelle einer lokalen Variablen an einem bestimmten Punkt verwenden? – Chuck

+0

Kannst du deinen Code hinzufügen, wie du 'Anfrage' zusammenhältst? – vikingosegundo

+0

Aber das ist nicht dein Code. – vikingosegundo

Antwort

1

-[NSCFNumber count]: unrecognized selector sent to instance 0x100506a20 bedeutet, dass Sie Count auf ein NSCFNumber-Objekt aufrufen, aber NSCFNumber hat diese Methode nicht.Die wahrscheinlichste Anzahl wird also an ein freigegebenes NSArray- oder NSSet-Objekt gesendet.

USE NSZombieEnabled = YES. Es könnte Ihnen sagen, was passiert. Suchen Sie SO nach Informationen zur Einstellung.

+0

'NSZombieEnabled' hat mir nichts gesagt. Außerdem wird der Selektor irgendwo aus dem API-Code gesendet, nicht in irgendetwas, das ich geschrieben habe (von dem ich weiß). – Dov

+0

Der Systemcode könnte leicht an ein Array, Set oder ein Wörterbuch gesendet werden, das von Ihrem Code freigegeben wurde. Nach der Freigabe wird eine neue NSNummer an derselben Stelle zugewiesen, an der das Array, der Satz oder das Wörterbuch verwendet wurde. –

+0

Wenn das der Fall ist, wie würde ich herausfinden, welches Objekt das Problem verursacht? Gibt es ein Instrument oder etwas, das helfen könnte? – Dov

3

Wenn Sie Speicherverwaltung Probleme haben (Selektoren an die falschen Instanzen gesendet wird, ist ein Zeichen von Speicher-Management-Themen), gibt es eine Reihe von Dingen, die Sie tun können:

  1. Re-lesen Sie die Cocoa memory management rules und vergewissere dich, dass du ihnen folgst.
  2. Führen Sie die static analyser. Dies wird oft Orte aufgreifen, an denen Sie die Speicherverwaltungsregeln vernachlässigt haben.
  3. Verwenden Sie NSZombieEnabled, um herauszufinden, ob [und wann] Nachrichten an nicht zugeordnete Instanzen gesendet werden.
+0

Ich starte den statischen Analysator sehr häufig, und NSZombieEnabled zeigte nichts. Ich kann die Speicherverwaltungsregeln jedoch noch einmal lesen. – Dov

+0

Wenn Sie Probleme mit den Kerndaten haben (der Wechsel des Geschäftstyps, der seltsame Fehler erzeugt, ist ein Zeichen für Core Data-Probleme), gibt es immer eine Cookie-Cutter-Antwort. –

0

Nach genau das gleiche Problem mit genau dem gleichen Beispielcode zu erfahren, für mich ist es endlich geklappt, nachdem ich [request release]in setzen.

+0

Nein, es hat doch nicht funktioniert. Allerdings fand ich dies in der [Dokumentation] (http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSExpressionDescription_Class/NSExpressionDescription.html) und denke, es könnte mit dem Problem zusammenhängen, aber ich bin es auch Neu in Core Data, um sicher zu sein: "Diese Methode löst eine Ausnahme aus, wenn das Modell des Empfängers von einem Objektgraphenmanager verwendet wurde." – stifin

+0

Ich habe definitiv aufgehört, diesen Fehler nach dem Entfernen von '[Anfrage setResultType: NSDictionaryResultType];' insgesamt (nicht nur mit "NSManagedObjectResultType", wie Sie in "Update 3" ersetzen. Allerdings ist der Wert zurückgegeben manchmal ungenau. Es ist wie es ist eine Verzögerung dort: wenn ich _increment den Wert mehrfach wiederhole, zu einem neuen Objekt speichere, Max wieder erhalte, repeat_, manchmal 2 oder 3 Objekte hintereinander sind nicht inkrementiert worden, aber haben Duplikate – stifin

1

Dies kann auch passieren, wenn eine Bindung nicht korrekt eingestellt ist. Wenn Sie beispielsweise einen booleschen Matrixwert an "Inhalt" anstelle von (oder zusätzlich zu) "Ausgewähltes Tag" in IB binden, können Sie diesen Fehler erhalten.

Wenn alles andere fehlschlägt, trennen Sie alle Ihre Bindungen und verbinden sie einzeln nacheinander, um zu sehen, welcher der Schuldige ist.

0

Sie verwenden den Schlüsselpfad: sortOrder in Ihrem Pfadausdruck. Zumindest für XML-Datenbanken Core-Data kann nicht von Groß-und Kleinschreibung Typen. Ändern Sie Ihren Pfad zu sortorder (alle Kleinbuchstaben)

Sie werden wahrscheinlich über weitere Probleme stolpern, wenn Sie Controller-Klassen verwenden.

+0

Danke für die Eingabe Ich benutze kein XML Backing-Store mehr, aber das ist gut zu wissen. – Dov

10

Offenbar ist dies ein bekannter Fehler, der bei Verwendung eines NSInMemoryStoreType-Datenspeichers auftritt. Es scheint, es funktioniert gut mit einem NSSQLiteStoreType.

You can find the OpenRadar entry here

ich ein Duplikat für diesen Fehler gefüllt - ich Menschen ermutigen, die das gleiche Problem auftreten, das gleiche zu tun, wird die Wahrscheinlichkeit, dieses lästige Verhalten dokumentiert zu erhöhen (oder noch besser, fest).

+0

Dies ist nützliche Informationen, aber wie in der Frage erwähnt, verwende ich 'NSSQLiteStoreType', nicht' NSInMemoryStoreType'. – Dov

+0

Vielleicht, wenn einige automatische Speicherung abgeschlossen ist, 'NSInMemoryStoreType' verwendet wird. Ich bin genau in der gleichen Situation wie du. Manchmal stürzt es ab, manchmal nicht t Wenn das Programm versucht, ein geschlossenes Dokument zu öffnen, das automatisch gespeichert wurde (wo übrigens!), aber nicht gespeichert wurde, stürzt es ab. – Colas