Why did unmodeled property reap guilt?

since we know that the properties of NSFetchRequestToFetch can limit the required properties, this can reduce the amount of memory. If we do it like this:

request.propertiesToFetch = [NSArray arrayWithObjects:@"nID", nil]; 

and

  NSString *strID = [NSString stringWithFormat:@"%@", aPerson.nID]; cell.textLabel.text = strID; 

then debug output (not fire error):

 CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.ZNID FROM ZPERSON t0 ORDER BY t0.ZNID 

A strange thing happened, however, when I add a new unmodeled property to a subclass of NSManagedObject Person. Similar:

 @interface Person (Ex) @property (nonatomic, retain) NSString *strTempName; @end @implementation Person (Ex) @dynamic strTempName; -(void)setStrTempName:(NSString *)strTempName { [self setPrimitiveValue:strTempName forKey:@"strTempName"]; } -(NSString*)strTempName { return [self primitiveValueForKey:@"strTempName"]; } 

And here a new unmodeled property opens:

 NSString *strTT = aPerson.strTempName; 

then debug output:

 2013-05-06 10:43:07.789 TestCoreData[988:c07] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBISFORTEST, t0.ZBISINTRASH, t0.ZNID, t0.ZSTRNAME, t0.ZSTROK, t0.ZSTROK2, t0.ZSTRTEST1, t0.ZSTRTEST2, t0.ZADEPART, t0.ZAMIDDLETHUMNAIL, t0.ZANORMALPIC, t0.ZASMALLTHUMNAIL FROM ZPERSON t0 WHERE t0.Z_PK = ? 2013-05-06 10:43:07.790 TestCoreData[988:c07] CoreData: annotation: sql connection fetch time: 0.0010s 2013-05-06 10:43:07.791 TestCoreData[988:c07] CoreData: annotation: total fetch execution time: 0.0018s for 1 rows. 2013-05-06 10:43:07.792 TestCoreData[988:c07] CoreData: annotation: fault fulfilled from database for : 0x898a030 <x-coredata://CAD35D43-F6B2-4463-B59B-C9A3CD488935/Person/p51846> 

From the output message above we can find a non-model property caused by the fact that instead of SELECT t0.Z_ENT, t0.Z_PK, t0.ZNID, SELECT all property sentences are generated and an error is triggered!

however, I read a few posts about the unmodeled property ( here is the link ):

Because unmodeled properties are only attributes of a custom NSManagedObject Subclass, not an object, failure objects know nothing about them. Damage objects are initialized from the data model so that all keys to which they respond must be in the data model. This means that faults will not reliably respond to a request for unmodeled properties.

why did the strange happen?

early.


@Anonymous,

choice 1): the application crashed and the debug output showed:

 2013-05-06 14:03:05.665 TestCoreData[1794:c07] -[Person strTempName]: unrecognized selector sent to instance 0x6ba77b0 2013-05-06 14:03:30.395 TestCoreData[1794:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person strTempName]: unrecognized selector sent to instance 0x6ba77b0' 

2) choice: firstly, methods like willAccessValueForKey, etc., should send a KVO change notification, just like comments in NSManagedObject.h:

 - (void)willAccessValueForKey:(NSString *)key; // read notification - (void)didAccessValueForKey:(NSString *)key; // read notification (together with willAccessValueForKey used to maintain inverse relationships, to fire faults, etc.) 

secondly, the next choice is 2) the code, the strange thing (for troubleshooting) is still alive in my application.

also thanks to your answer.

+4
source share
3 answers

Things are going wrong:

First: It is correct that @dynamic is wrong. Accessors are in your code. There is nothing dynamic.

Second: primitive accessors are for simulated properties. You have the property "ivar". Just use it the way you will use it elsewhere. (But add ... access ... and ... change ... methods.)

After this has been changed, repeat the check to see if errors will be generated.

+++ In the -didAccessValueForKey: (NSManagedObject) clause, you will find a sample for the correct implementation:

 - (NSString *)firstName { [self willAccessValueForKey:@"firstName"]; NSString *rtn = firstName; [self didAccessValueForKey:@"firstName"]; return rtn; } 
0
source

return [self primitiveValueForKey:@"strTempName"];

It is not right. primitiveValueForKey used to access the simulated property. Since your property is not modeled, you get all the strange behavior: the main data crashes because it searches for the property and, when it does not find it, throws an exception.

What do you want to achieve? Maybe you are looking for a transient property, or maybe you just need to synthesize the property, as in any other object?

0
source

I think you encoded too much. @dynamic generates your getters and setters for you. You have two options.

1) Remove the setter / getter calls.

2) Change your recipients / setters to warn the system that you are changing values:

 -(void)setStrTempName:(NSString *)strTempName { [self willChangeValueForKey:@"strTempName"]; [self setPrimitiveValue:strTempName forKey:@"strTempName"]; [self didChangeValueForKey:@"strTempName"]; } -(NSString*)strTempName { [self willAccessValueForKey:@"strTempName"]; NSString *tmp = [self primitiveValueForKey:@"strTempName"]; [self didAccessValueForKey:@"strTempName"]; return tmp; } 
-1
source

Source: https://habr.com/ru/post/1479290/


All Articles