본문 바로가기
프로그래밍 놀이터/iOS

[ios] NSExpression with CoreData

by 돼지왕 왕돼지 2017. 12. 3.
반응형

 [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

column, com.apple.CoreData.SQLDebug 1, CoreData, debug console, executeFetchRequest, expressionForFunction, expressionForKeyPath, fetch, fetchrequest, launch arguments, Max, median, Min, nsdictionaryresulttype, NSEntityDescription, NSExpression, nsexpression 함수, NSExpressionDescription, NSFetchRequest, NSNumberAttributeType, query optimize, query 성능 측정, setExpression, setExpressionResultType, setPropertiesToFetch, setresulttype, sort order, SQRT, Sum, [ios] NSExpression with CoreData, 성능 측정, 성능 향상, 조건, 최대값, 최소값, 코드양


-

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”];




반응형

댓글