需要从nsarray for loop-iphone更新nsmanagedobject

需要从nsarray for loop-iphone更新nsmanagedobject,iphone,ios,nsmanagedobject,Iphone,Ios,Nsmanagedobject,我有一个coredata项目,我正试图以编程方式更新一个数字。 我从CoreData中检索对象,然后将其存储到数组中 然后,我将遍历该数组,查看当前用户的IP是否存在于数据库中,并尝试更新该特定数组的访问次数 问题是,它正在更新所有对象,而不仅仅是循环数组中的当前对象 首先,我从核心数据中获得如下信息: - (void)fetchRecords { // Define our table/entity to use NSEntityDescription *entity = [

我有一个coredata项目,我正试图以编程方式更新一个数字。 我从CoreData中检索对象,然后将其存储到数组中

然后,我将遍历该数组,查看当前用户的IP是否存在于数据库中,并尝试更新该特定数组的访问次数

问题是,它正在更新所有对象,而不仅仅是循环数组中的当前对象

首先,我从核心数据中获得如下信息:

- (void)fetchRecords {

    // Define our table/entity to use
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"IPAddr" inManagedObjectContext:managedObjectContext];

    // Setup the fetch request
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];

    // Define how we will sort the records
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"ipDate" ascending:NO];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    [request setSortDescriptors:sortDescriptors];


    // Fetch the records and handle an error
    NSError *error;
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];

    if (!mutableFetchResults) {
        // Handle the error.
        // This is a serious error and should advise the user to restart the application
    }

    // Save our fetched data to an array
    [self setIpArray: mutableFetchResults];

}
现在,我尝试查找当前用户IP是否存在于获取的结果中,如果存在,则更新访问次数:

// see if the ip is present and update if necessary
-(void)ipPresent {
    NSString * theCurrentIP = [self getGlobalIPAddress];
    for (IPAddr *allips in ipArray)
    {
        if ([allips.ipNum isEqualToString:theCurrentIP]) {
            NSLog(@"The IP %@ was found.", theCurrentIP);

            // update the ip

            NSError *error = nil;

            NSNumber *ipToUpdate = allips.ipAccess;

            NSNumber *addIpAccess = [[NSNumber alloc] initWithInt:1];
            NSNumber *updateIpAddress = [NSNumber numberWithFloat:([ipToUpdate floatValue] + [addIpAccess floatValue])];

            [self.ipArray setValue:updateIpAddress forKey:@"ipAccess"];


            if ([self.managedObjectContext save:&error]) {  // write to database
            NSLog(@"The IP Was Updated from %@ to %@", ipToUpdate, updateIpAddress);
            } else if (![self.managedObjectContext save:&error]) {
                NSLog(@"failed with error: %@", error);
            }
            break;

        } else {
            NSLog(@"The IP %@ was NOT found.", theCurrentIP);

        }
    }
} 
我很确定问题出在这一行:

[self.ipArray setValue:updateIpAddress forKey:@"ipAccess"];

同样,它正在更新所有实体,而不仅仅是当前循环中的实体。

的确如此。你使用了错误的方法
self.ipArray
是一个
NSMutableArray

方法

- (void)setValue:(id)value forKey:(NSString *)key
用于键值编码(这使其适用于核心数据对象),但当应用于数组时,它将在数组中的每个条目上调用setValue:forKey:

现在,您可以看到,您还可以在单个数组元素
allips
上调用
setValue:forKey
,因为它的属性显然与KVC兼容——否则您将遇到不同的问题,无法看到正在设置的值

请注意,您也可以只指定属性

allips.ipAccess = updateIpAddress;
编辑

对不起,可能应该读慢一点。。。您知道您不必使用可变数组,对吗?实际上,您并没有更改数组,只是更改数组中的元素。不可变集合意味着集合内容不能更改,但当您有一个指向某个对象的指针时,只要该对象不是不可变的,您仍然可以更改其属性

因此,如果您有一个不可变的Foo对象数组,您可以这样做

for (Foo *foo in myImmutableArray) {
    Bar *bar = [self getSomeNewBar];
    [foo setBar:bar];

    // If Foo is KVC compliant, you can do this too...
    [foo setValue:bar for Key:@"bar"];
}
但是,如果在数组上调用
setValue:forKey
,则将为数组的每个元素调用它。注意,
setValue:forKey
实际上是在不可变NSArray中声明的

编辑

这句话很难理解


核心数据对象只是另一个对象。看起来您已经对它进行了子类化,并为它提供了属性的属性。替换

[self.ipArray setValue:updateIpAddress forKey:@"ipAccess"];

其中任何一个都应该修改您的核心数据对象,就像它们修改任何具有名为“ipAccess”的读/写属性的对象一样


当然,假设我没有再读错。。。allips是您的核心数据对象…

嗨,Jody,对不起,我是IOS新手,所以我正在尝试解决这个问题。。。我将如何在上面的代码中实现这一点?此外,我正在尝试更新CoreData对象,而不仅仅是当前数组。谢谢核心数据对象只是另一个对象。看起来您已经对它进行了子类化,并为它提供了属性的属性。只需替换为或完美!成功了。非常感谢!我是一名PHP程序员,正在尝试通过IOS来实现自己的目标。:)祝你好运这里有很多iOS新手。很高兴看到您确实有一个经过深思熟虑的问题,并准备好了代码。顺便说一句,这个错误很容易犯。我建议,既然您为核心数据对象创建了一个子类,那么您就应该使用这些属性。它可以减少您的一些错误,因为一堆对象响应
setValue:forKey:
谢谢您的建议!我使用的是一个“预打包”的核心数据表视图控制器,但我觉得它似乎只是为UITableViewController设计的,无法与UITableView一起使用。
[allips setValue:updateIpAddress forKey:@"ipAccess"];
allips.ipAccess = updateIpAddress;