2009-10-21 3 views
10

상당히 간단한 데이터 모델을 사용하는 핵심 데이터 앱이 있습니다. 공간을 절약하기 위해 PNG 비트 맵 NSData 객체로 영구 저장소에 NSImage의 인스턴스를 저장할 수 있기를 원합니다.변환 가능한 핵심 데이터 속성이 내 사용자 지정 NSValueTransformer를 사용하지 않는 이유는 무엇입니까?

이 목적을 위해 간단한 NSValueTransformer를 작성하여 NSImage를 PNG 비트 맵 형식의 NSData로 변환했습니다. 내 응용 프로그램 위임에이 코드 값 변압기를 등록하고 :

+ (void)initialize 
{ 
    [NSValueTransformer setValueTransformer:[[PNGDataValueTransformer alloc] init] forName:@"PNGDataValueTransformer"]; 
} 

을 내 데이터 모델에서, 나는, 변형 할 이미지 속성을 설정하고 값 변압기 이름으로 PNGDataValueTransformer 지정했습니다.

그러나 사용자 정의 값 변환기가 사용되지 않습니다. 로그에 기록되지 않는 값 변환기의 -transformedValue:-reverseTransformedValue 메소드에 로그 메시지를 넣었 기 때문에 디스크에 저장되는 데이터는 보관 된 NSImage가 아니라 PNG NSData 객체입니다.

왜 작동하지 않습니까?

@implementation PNGDataValueTransformer 

+ (Class)transformedValueClass 
{ 
    return [NSImage class]; 
} 

+ (BOOL)allowsReverseTransformation 
{ 
    return YES; 
} 

- (id)transformedValue:(id)value 
{ 
    if (value == nil) return nil; 
    if(NSIsControllerMarker(value)) 
     return value; 
    //check if the value is NSData 
    if(![value isKindOfClass:[NSData class]]) 
    { 
     [NSException raise:NSInternalInconsistencyException format:@"Value (%@) is not an NSData instance", [value class]]; 
    } 
    return [[[NSImage alloc] initWithData:value] autorelease]; 
} 

- (id)reverseTransformedValue:(id)value; 
{ 
    if (value == nil) return nil; 
    if(NSIsControllerMarker(value)) 
     return value; 
    //check if the value is an NSImage 
    if(![value isKindOfClass:[NSImage class]]) 
    { 
     [NSException raise:NSInternalInconsistencyException format:@"Value (%@) is not an NSImage instance", [value class]]; 
    } 
    // convert the NSImage into a raster representation. 
    NSBitmapImageRep* bitmap = [NSBitmapImageRep imageRepWithData: [(NSImage*) value TIFFRepresentation]]; 
    // convert the bitmap raster representation into a PNG data stream 
    NSDictionary* pngProperties = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:NSImageInterlaced]; 
    // return the png encoded data 
    NSData* pngData    = [bitmap representationUsingType:NSPNGFileType properties:pngProperties]; 
    return pngData; 
} 

@end 

답변

0

코드에서 전혀 다른 곳에서 명시 적으로 해당 클래스가 호출되지 않습니다를 들어, 다음 +이 방법을 초기화 PNGDataValueTransformer 클래스를 사용하지 않는 경우 : 여기

내 가치 변압기의 코드입니다. 코어 데이터 모델에서 이름을 지정해도 해당 이름에 대한 값 변환기가 검색되지는 않습니다.이 이름에 대한 변환기 인스턴스가 아직 등록되지 않았으므로 nil을 반환합니다.

실제로 발생한 상황 인 경우 데이터 모델에 액세스하기 전에 코드의 [PNGDataValueTransformer initialize]에 대한 호출을 추가하기 만하면됩니다. 어떤 클래스의 + initialize 메소드에서이 데이터 모델을 사용하고있다. 그러면 코어 데이터가 필요할 때 액세스 할 수 있도록 값 변환기 인스턴스가 생성되고 등록되어야합니다.

+0

안녕 브라이언의'+ initialize' 방법은 내 응용 프로그램 위임에 값이 아닌, 변압기와 나는 확실히 확인할 수 있습니다 그것은 불리고있다. 내 NSValueTransformer의'-init' 메소드에 중단 점을 넣으면 확실히 초기화됩니다. "binary"유형으로 속성을 설정하고 IB의 각 바인딩에 값 변환기를 적용하면 정상적으로 작동합니다. 속성 형식을 변형 가능으로 지정할 때 사용자 지정 변환기가 사용되지 않는 이유를 이해하지 못합니다. –

25

내가 실수가 아니라면 값 변압기의 방향이 반대가됩니다. 나는 다음과 같은 코드를 사용하여 내 응용 프로그램에서 같은 일을 :이 아이폰 동안

+ (Class)transformedValueClass 
{ 
return [NSData class]; 
} 

+ (BOOL)allowsReverseTransformation 
{ 
return YES; 
} 

- (id)transformedValue:(id)value 
{ 
if (value == nil) 
    return nil; 

// I pass in raw data when generating the image, save that directly to the database 
if ([value isKindOfClass:[NSData class]]) 
    return value; 

return UIImagePNGRepresentation((UIImage *)value); 
} 

- (id)reverseTransformedValue:(id)value 
{ 
return [UIImage imageWithData:(NSData *)value]; 
} 

, 당신은 적절한 위치에 당신의 NSImage 코드에서 교환 할 수 있어야한다. Mac 구현을 아직 테스트하지 않았습니다.

데이터 모델 내에서 변환 가능한 이미지 속성을 설정하고 변압기의 이름을 지정하기 만하면됩니다. + 초기화 메소드에서와 같이 값 변환기를 수동으로 등록 할 필요가 없습니다.

+0

Brad에게 감사합니다. 나는 이것을 시도했지만 아무런 차이가 없었고, 나의 가치 변압기는 무시되었다. –

2

변압기를 등록하는 것이 더 핵심적인 데이터에 영향을주지 않는 것으로 보이거나 사용하지 않을 것입니다. PhotoLocations 샘플 코드를 가지고 놀았으므로 변압기 등록을 제거해도 효과가 없습니다. ValueTransformerName이 클래스의 이름이고 트랜스 포머의 구현이 타겟에 포함되어 있다면 작동해야합니다.

변압기에 코드 실행이없는 경우 변압기의 코드는 부적합합니다. 문제는 핵심 데이터 스택의 다른 곳이나 변압기 선언에 있어야합니다.

+0

동일 함! 해결책을 찾았습니까? – webmastx

0

예제 코드 here을 확인하십시오.

원하는대로 할 수 있습니까?

@implementation UIImageToDataTransformer 


+ (BOOL)allowsReverseTransformation { 
    return YES; 
} 

+ (Class)transformedValueClass { 
    return [NSData class]; 
} 


- (id)transformedValue:(id)value { 
    NSData *data = UIImagePNGRepresentation(value); 
    return data; 
} 


- (id)reverseTransformedValue:(id)value { 
    UIImage *uiImage = [[UIImage alloc] initWithData:value]; 
    return [uiImage autorelease]; 
} 
1

명시 적으로 실행하는 동안 변압기를 등록해야합니다.

NSManagedObject 엔터티 하위 클래스의 클래스 초기화 메서드를 재정의하는 것이 좋습니다. 앞서 언급했듯이 코어 데이터 버그입니다. 애플의 위치 코드 샘플에서 중요한 코드는 다음, 그것을 테스트 및 작동 : http://developer.apple.com/library/ios/#samplecode/Locations/Introduction/Intro.html

+ (void)initialize { 
    if (self == [Event class]) { 
     UIImageToDataTransformer *transformer = [[UIImageToDataTransformer alloc] init]; 
     [NSValueTransformer setValueTransformer:transformer forName:@"UIImageToDataTransformer"]; 
    } 
} 
+0

예, 저는 이것을 알고 있으며 저는 그것을하고 있습니다. –

+0

제 경우에는 정확하게 문제였습니다. 변환 자 이름이 데이터 모델에서 선언 한 것과 일치하는지 그리고 메소드의 본문을 inverseValue 및 reverseTransformedValue와 비교하지 않았는지 확인할 수도 있습니다. – Lukasz

관련 문제