Ваша переменная fetchedResults
содержит объект NSArray.Однако NSArray может содержать любую произвольную группу объектов.В отличие от стандартного массива C, не требуется, чтобы все объекты NSArray были одного класса.
Точечная нотация, которую вы здесь используете:
[fetchResults objectAtIndex:i].UserID =
... хотя допустимый синтаксис, тем не менее, приводит в замешательство компилятор, потому что компилятор не знает, какой класс объекта возвращается [fetchResults objectAtIndex:i]
.Не зная класса, он понятия не имеет, что за хрень UserID
.Отсюда и ошибка "request for member 'UserID' in something not a structure or union"
.По крайней мере, вы должны привести приведение [fetchResults objectAtIndex:i]
к какому-либо классу, чтобы у компилятора была подсказка, что такое «UserID».
Однако вы не должны использовать эту конструкцию, даже если она законна, потому что она опасна.См. Ниже форму наилучшей практики.
Понимание NSManagedObject и его подклассов может быть сложным, поскольку сам NSManagedObject использует трюк с именем associative storage
, который позволяет любым универсальным экземплярам NSManagedObject сохранять любое свойство любого объекта, определенного в любой модели.Это может сбить с толку новичков, поскольку существует несколько способов ссылаться на одни и те же объекты, экземпляры и свойства.Иногда в примерах используются общие NSMangedObjects и setValue:forKey:
/ valueForKey:
, а в других случаях они используют objectInstance.propertyName
.
Ассоциативное хранилище работает как словарь, прикрепленный к каждому экземпляру класса NSManagedObject.Когда вы вставляете универсальный NSManagedObject следующим образом:
NSManagedObject *mo=[NSEntityDescription insertNewObjectForEntityForName:@"User"
inManagedObjectContext:self.managedObjectContext];
... вы получаете экземпляр класса NSManageObject, для ассоциативных ключей хранения которого установлены свойства сущности User
, как определено в вашей модели данных,Затем вы можете установить и получить значения, используя кодирование значения ключа (которое имеет тот же синтаксис, что и словари), таким образом:
[mo setValue:@"userid0001" forKey:@"UserID"];
NSString *aUserID=[mo valueForKey:@"UserID"];
Ассоциативное хранилище позволяет вам представлять любую сложную модель данных в коде без необходимости написания каких-либо пользовательскихNSManagedObject подклассы.(В Какао он позволяет вам использовать привязки, которые позволяют создавать целые программы без написания какого-либо кода управления данными.)
Однако общий класс NSManagedObject немного лучше, чем прославленный словарь, чье сохранение и чтениеобрабатывается автоматически.Если вам нужны объекты данных с настраиваемым поведением, вам нужно явно определить подкласс NSManagedObject.Если вы позволите Xcode сгенерировать класс из сущности в модели данных, то в итоге вы получите исходный файл, например:
User.h
@interface User : NSManagedObject
{
}
@property (nonatomic, retain) NSString * firstName;
@property (nonatomic, retain) NSString * userID;
@property (nonatomic, retain) NSString * lastName;
@end
User.m
#import "User.h"
@implementation User
@dynamic firstName;
@dynamic userID;
@dynamic lastName;
@end
Теперь вы больше не ограничены синтаксисом ключ-значение ассоциативного хранилища.,Вы можете использовать точечный синтаксис, потому что у компилятора есть класс для ссылки:
User *aUser=[NSEntityDescription insertNewObjectForEntityForName:@"User"
inManagedObjectContext:self.managedObjectContext];
aUser.userID=@"userID0001";
NSString *aUserID=aUser.userID;
С учетом всего этого становятся понятными правильные формы ссылки на массив fetchedResults
.Предположим, вы хотите установить для всех свойств userID одно значение по умолчанию.Если вы используете универсальный класс NSManagedObject, который вы используете:
for (NSManagedObject *aMO in fetchedResults) {
[aMO setValue:@"userid0001" forKey:@"UserID"];
NSString *aUserID=[aMO valueForKey:@"UserID"];
}
Если вы используете выделенный подкласс, вы должны использовать:
for (User *aUserin fetchedResults) {
aUser.userID=@"userID0001";
NSString *aUserID=aUser.userID;
}
(Примечание: вы всегда можете использовать универсальную форму для всехNSManagedObject подклассы также.)