프로그래밍 놀이터/iOS

[ios] NSExpression with CoreData

돼지왕 왕돼지 2017. 12. 3. 08:30
반응형

 [ios] NSExpression with CoreData


http://useyourloaf.com/blog/core-data-queries-using-expressions/

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSExpression_Class/#//apple_ref/doc/uid/TP30001190-SW38


-

Query 문 성능 측정을 위해서는 launch arguments 에 다음을 추가해야 한다.

-com.apple.CoreData.SQLDebug 1


그럼 Debug Console 에서 아래와 같은 로그를 볼 수 있다.

2012-01-19 20:31:37.864 ToDoSync[3455:fb03] CoreData: sql: SELECT 0,

t0.Z_PK, t0.Z_OPT, t0.ZCOMPLETE, t0.ZCREATEDAT, t0.ZNOTE, t0.ZTITLE FROM

ZTASK t0 ORDER BY t0.ZCREATEDAT LIMIT 1

2012-01-19 20:31:37.875 ToDoSync[3455:fb03] CoreData: annotation: sql

connection fetch time: 0.0742s

2012-01-19 20:31:37.875 ToDoSync[3455:fb03] CoreData: annotation: total

fetch execution time: 0.0784s for 1 rows.



-

CoreData 로부터 Fetch 를 할 때 특정 Column 값만 가져오고 싶다면...

아래와 같이 fetchRequest 조건을 추가해주면 된다.

NSDictionaryResultType 을 주는 이유는 Column 값이 2개 이상일 경우 columName 을 key 로 value 에 접근하기 위함이다.

[fetchRequest setResultType:NSDictionaryResultType];

[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:@“columnName”]];



-

특정 Column 만 가져오는 것은 성능 향상 효과가 있다.



-

Expression 을 사용하면, 최대값, 최소값을 찾는 듯의 query 를 좀 더 optimize 할 수 있다.

NSExpression 을 사용하지 않으면, Sort order 를 통해 찾아야 하는데, 약간 비효율적이다.


NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription* entity = [NSEntityDescription entityForName:@“tableName” inManagedObjectContext:self.context];

[fetchRequest setEntity:entity];

[fetchRequest setResultType:NSDictionaryResultType];


NSExpression* keyPathExpression = [NSExpression expressionForKeyPath:@“columnName”];

NSExpression* minValueExpression = [NSExpression expressionForFunction:@“min:” arguments:[NSArray arrayWithObject:keyPathExpression]];


NSExpressionDescription* minValueExpressionDescription = [[NSExpressionDescription alloc] init];

[minValueExpressionDescription setName:@“minValue”]; //결과 Dictionary 에 들어갈 key

[minValueExpressionDescription setExpression:minValueExpression];

[minValueExpressionDescription setExpressionResultType:NSNumberAttributeType]; // 결과 Dictionary 에 들어갈 value type


[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:minValueExpressionDescription]];

NSError* error = nil;

NSArray* fetchResults = [self.context executeFetchRequest:fetchRequest error:&error];


NSNumber* minValue = [[fetchResults lastObject] valueForKey:@“minValue”];



-

NSExpression 에 적용 가능한 함수들은 아래와 같다.


sum:

min:

max:

median:

sqrt:

…. ( 기타 등등 )



-

NSExpression 을 사용하면, 코드 양은 훨씬 늘어날 수 있지만 엄청난 성능 향상이 있을 수 있다.



-

NSExpression 은 여러개의 연산을 한 번에 처리할 때 더 빛을 발한다.

예를 들어, min 과 max 둘 다 구하고 싶다면 아래와 같이 한 fetch 에 2개의 expressionDescription 을 넣어서 돌리면 dictionary 형태로 2개의 값을 한번에 받을 수 있다.

게다가 성능도 훨씬 좋다.

NSExpression* maxExpression = [NSExpression expressionForFunction:@“max:” arguments:@[keyPathExpression];

NSExpressionDescription* maxExpressionDescription = [[NSExpressionDescription alloc] init];

[maxExpressionDescription setName:@“maxValue”];

[maxExpressionDescription setExpression:maxExpression];

[maxExpressionDescription setExpressionResultType:NSNumberAttributeType];


[fetchRequest setPropertiesToFecth:@[minValueExpressionDescription, maxValueExpressionDescription];


NSError* error;

NSArray* fetchResults = [self.context executeFetchRequest:fetch error:&error];


NSNumber* minValue = [[fetchResults lastObject] valueForKey:@“minValue”];

NSNumber* maxValue = [[fetchResults lastObject] valueForKey:@“maxValue”];




반응형