Вы пытаетесь использовать Базовые данные как процедурную базу данных, а не как менеджер графов объектов, как предполагал API, поэтому вы не найдете простого способа сделать это.
Нет прямого способа сделать это в Базовых данных, потому что Базовые данные связаны с объектами, а не со значениями. Поскольку управляемые объекты гарантированно являются уникальными, базовые данные не очень заботятся о значениях каждого объекта или о том, являются ли они дубликатами или значениями некоторых других объектов.
Чтобы найти уникальные значения:
name
и значением самой строки имени. Итак, что-то вроде:
NSSet *uniqueNames=[fetchedNameDicts valueForKeyPath:@"@distinctUnionOfSets.name"];
... который вернет набор объектов NSString с уникальным значением.
Я слышал, как Андре Панг на конференции NSConference рассказывал о том, как блоки будут представлены в следующей версии Objective-C.
Это должно позволить функциональное программирование.
Редактировать: Since Snow Леопарда выпустили, это действительно так. Objective-C теперь имеет блоков .
В OS X 10.6 введены блоки. См. ответ AlBlue для примеров .
Если вы не используете Snow Leopard, вы можете получить что-то похожее на композицию функций, используя различные другие функции.
Пример использования указателей функций C:
void sayHello() {
NSLog(@"Hello!");
}
void doSomethingTwice(void (*something)(void)) {
something();
something();
}
int main(void) {
doSomethingTwice(sayHello);
return 0;
}
Пример использования шаблона команды:
@protocol Command <NSObject>
- (void) doSomething;
@end
@interface SayHello : NSObject <Command> {
}
@end
@implementation SayHello
- (void) doSomething {
NSLog(@"Hello!");
}
@end
void doSomethingTwice(id<Command> command) {
[command doSomething];
[command doSomething];
}
int main(void) {
SayHello* sayHello = [[SayHello alloc] init];
doSomethingTwice(sayHello);
[sayHello release];
return 0;
}
Пример использования селектора :
@interface SaySomething : NSObject {
}
- (void) sayHello;
@end
@implementation SaySomething
- (void) sayHello {
NSLog(@"Hello!");
}
@end
void doSomethingTwice(id<NSObject> obj, SEL selector) {
[obj performSelector:selector];
[obj performSelector:selector];
}
int main(void) {
SaySomething* saySomething = [[SaySomething alloc] init];
doSomethingTwice(saySomething, @selector(sayHello));
[saySomething release];
return 0;
}
Концепция лямбда-выражения в Objective-C теперь инкапсулирована идеей блоков , которые являются эквивалентом функций передачи по ссылке. Конечно, возможно, кто-то уже имел это в C с идеей указателей на функции; блоки - это всего лишь способ фиксации локального состояния (т. е. могут быть замыканиями). Фактически, блоки также могут использоваться в других языках C (на Mac) - есть предложение сделать их частью стандартного синтаксиса C.
Вот пример определения лямбда для умножения двух чисел:
int (^mult)(int, int) = ^(int a, int b) { return a*b; };
Первая часть объявляет переменную типа ^ int (int, int)
, а затем назначает ее лямбда-выражению (также известному как блок), которое возвращает кратное из двух своих аргументов. Затем вы можете передать эту функцию, определить ее в других местах и т. Д .; вы даже можете использовать его в других функциях.
Вот пример определения функции, которая при вызове возвращает другую функцию:
multiplyBy = ^(int a) { return ^(int b) { return b*a; }; };
triple = multiplyBy(3);
Обратите внимание, что вы можете смешивать блоки с типами объектов (обычно используя id
в качестве типа объекта) и многие из Новые структуры данных объектов Objective-C имеют своего рода операции на уровне блоков. GCD также использует блоки для передачи произвольных событий; однако обратите внимание, что GCD также можно использовать с указателями на функции.