gpt4 book ai didi

objective-c - IBAction 陷入循环

转载 作者:行者123 更新时间:2023-12-03 17:00:33 25 4
gpt4 key购买 nike

好的,我有一个与 iCal 同步的 IBAction,并且也由 CD 模型中“名称”属性的 KVO 触发,因此当属性更改时会触发操作。发生的情况是,一旦 IBAction 到达末尾,它就会跳到 KVO 声明,然后一次又一次地触发 Action,这就是循环发生的地方。

这是一些代码。 IBA行动...

- (IBAction)sync:(id)sender {
[syncButton setTitle:@"Syncing..."];
NSString *dateText = (@"Last Sync : %d", [NSDate date]);
[syncDate setStringValue:dateText];
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:@"projects" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];

NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
NSAlert *anAlert = [NSAlert alertWithError:error];
[anAlert runModal];
}
NSArray *namesArray = [array valueForKey:@"name"];
NSPredicate *predicate = [CalCalendarStore taskPredicateWithCalendars:[[CalCalendarStore defaultCalendarStore] calendars]];
NSArray *tasksNo = [[CalCalendarStore defaultCalendarStore] tasksWithPredicate:predicate];
NSArray *tasks = [tasksNo valueForKey:@"title"];
NSMutableArray *namesNewArray = [NSMutableArray arrayWithArray:namesArray];
[namesNewArray removeObjectsInArray:tasks];
NSLog(@"%d", [namesNewArray count]);
NSInteger *popIndex = [calenderPopup indexOfSelectedItem];

//Load the array
CalCalendarStore *store = [CalCalendarStore defaultCalendarStore];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *supportDirectory = [paths objectAtIndex:0];
NSString *fileName = [supportDirectory stringByAppendingPathComponent:@"oldtasks.plist"];

NSMutableArray *oldTasks = [[NSMutableArray alloc] initWithContentsOfFile:fileName];
[oldTasks removeObjectsInArray:namesArray];
NSLog(@"%d",[oldTasks count]);
//Use the content
NSPredicate* taskPredicate = [CalCalendarStore taskPredicateWithCalendars:[[CalCalendarStore defaultCalendarStore] calendars]];
NSArray* allTasks = [[CalCalendarStore defaultCalendarStore] tasksWithPredicate:taskPredicate];

// Get the calendar
CalCalendar *calendar = [[store calendars] objectAtIndex:popIndex];
// Note: you can change which calendar you're adding to by changing the index or by
// using CalCalendarStore's -calendarWithUID: method

// Loop, adding tasks
for(NSString *title in namesNewArray) {
// Create task
CalTask *task = [CalTask task];
task.title = title;
task.calendar = calendar;

// Save task
if(![[CalCalendarStore defaultCalendarStore] saveTask:task error:&error]) {
NSLog(@"Error");
// Diagnostic error handling
NSAlert *anAlert = [NSAlert alertWithError:error];
[anAlert runModal];
}
}

NSMutableArray *tasksNewArray = [NSMutableArray arrayWithArray:tasks];
[tasksNewArray removeObjectsInArray:namesArray];
NSLog(@"%d", [tasksNewArray count]);
for(NSString *title in tasksNewArray) {
NSManagedObjectContext *moc = [self managedObjectContext];
JGManagedObject *theParent =
[NSEntityDescription insertNewObjectForEntityForName:@"projects"
inManagedObjectContext:moc];
[theParent setValue:nil forKey:@"parent"];
// This is where you add the title from the string array
[theParent setValue:title forKey:@"name"];
[theParent setValue:[NSNumber numberWithInt:0] forKey:@"position"];

}

for(CalTask* task in allTasks)
if([oldTasks containsObject:task.title]) {
[store removeTask:task error:nil];
}

// Create a predicate for an array of names.
NSPredicate *mocPredicate = [NSPredicate predicateWithFormat:@"name IN %@", oldTasks];
[request setPredicate:mocPredicate];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];

// Execute the fetch request put the results into array
NSArray *resultArray = [moc executeFetchRequest:request error:&error];
if (resultArray == nil)
{
// Diagnostic error handling
NSAlert *anAlert = [NSAlert alertWithError:error];
[anAlert runModal];
}

// Enumerate through the array deleting each object.
// WARNING, this will delete everything in the array, so you may want to put more checks in before doing this.
for (JGManagedObject *objectToDelete in resultArray ) {
// Delete the object.
[moc deleteObject:objectToDelete];
}
//Save the array
[namesArray writeToFile:fileName atomically:YES];
[syncButton setTitle:@"Sync Now"];
NSLog(@"Sync Completed");
}

当它到达末尾时(以某种方式)触发 KVO 声明......

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
[self performSelector:@selector(sync:)];
}

然后再次触发 IBAction。这就是循环发生的地方,因为它卡在这里并不断触发操作。

有人能弄清楚到底发生了什么吗???

最佳答案

您正在为任何符合 KVO 的属性触发选择器 sync:
您应该过滤使用同步方法更改的任何键路径以避免递归。

我会执行以下操作:

  • 设置断点并检查值keyPath 来找出哪个变化正在开始递归。
  • 过滤掉触发递归的键路径更改

  • 同步开始时分离所有观察者并在完成时重新附加它们

关于objective-c - IBAction 陷入循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1548291/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com