3

현재 API와 개발자 간의 상호 작용을 돕기 위해 iOS 용 객관적인 c 프레임 워크를 만드는 중입니다. 이 일환으로 개발자가 정보를 사용자에게 표시하는 데 사용할 수있는 다양한 읽기 전용 객체 배열을 반환합니다. 그러나 사용자에게 표시되는 개체가 프레임 워크에서만 제공되고 프레임 워크를 사용하여 개발자가 인스턴스화 할 수 없도록하고 싶습니다.프레임 워크에서 읽기 전용 객체의 인스턴스화 방지

현재 구현에서는 사용자 정의 생성자 초기화 프로그램을 사용하여 api에서 JSON을 가져 와서 인스턴스를 생성합니다. 내가 사용자 정의 생성자 초기화 프로그램에 액세스하는 것을 알고있는 유일한 방법은 헤더 파일에 정의를 넣는 것입니다.이 정의는 헤더 파일에 저장되어 개발자뿐만 아니라 개발자도 액세스 할 수 있습니다. 사용자가 기본 생성자 이니셜 라이저, -(id)init;을 사용하려고하면 불일치 예외가 발생할 수 있지만 자신의 JSON 문자열을 만들지 못하게하고 사용자 정의 생성자 이니셜 라이저를 호출 할 수 없습니다.

개인 프레임 워크를 사용하는 개발자의 방해로부터 개인 프레임 워크를 보호하기위한 올바른 접근 방법을 취하고 있습니까? 이러한 객체에서 데이터의 유효성을 확인하기 위해이 문제를 어떻게 해결할 수 있습니까?

출처 : Is it possible to make the -init method private in Objective-C?

+0

이것은 약간의 패배와 같습니다. 읽은 것처럼 다른 클래스가 객체에서 특정 메소드를 호출하지 못하게하는 방법은 없습니다. 왜 당신이 제외한 모든 클래스가 인스턴스화되지 않는 것이 중요합니까? 극단적 인 방법으로 웹 서비스에서 데이터를 가져 오는 경우 프레임 워크에서 객체를 사용하기 전에 서버 측에서 JSON에 암호화 방식으로 서명하고 서명을 확인할 수 있습니다. 그러나 이것은 [XY 문제] (http://meta.stackexchange.com/a/66378/201130)와 조금 비슷합니다. – bdesham

+0

개발자가 문제를 일으켜 프레임 워크를 해결하려고하는 경우에 따라 이것이 향후 사용을 고려하는 경로 일 수 있습니다. 제안 해 주셔서 감사합니다. – Krejko

답변

3

당신은 매우 자연,의에 의해 오브젝티브 C는 진정으로 개인 방법을 허용하지 않습니다 올바른지 인해 다이나믹 디스패치 시스템에 관한 것이다. 그러나 귀하의 질문이 진정한 보안에 관한 것이 아니라 잘못된 방식으로 프레임 워크를 사용하는 것을 어렵게 만드는 것이 아니라면 몇 가지 옵션이 있습니다.

간단하고 일반적인 해결책은 개별 헤더 파일의 범주에 공개하고 싶지 않은 메서드에 대한 선언을 넣는 것입니다. 이 메소드의 구현을 클래스의 메인 구현 파일에 넣을 수 있습니다. 그래서,이 같은 뭔가 헤더 :

// MyClass+Private.h 
@interface MyClass (Private) 
- (void)aPrivateMethod; 
@end 

그런 다음 자신의 소스 파일에 당신이 그 개인 방법, 당신이 단순히 수입 MyClass에 + Private.h 액세스해야합니다.

프레임 워크의 경우 각 헤더 파일을 공개 또는 비공개로 설정할 수 있습니다. 개인 헤더는 프레임 워크 번들에 복사되지 않으므로 프레임 워크의 사용자는 볼 수 없습니다. Xcode (오른쪽 슬라이드 아웃 창)에서 유틸리티 패널을 열고 문제의 헤더를 선택한 다음 "대상 멤버쉽"에서 관련 행의 두 번째 열에서 개인을 선택하여이 작업을 수행 할 수 있습니다.

+0

이것이 내가 찾고 있었던 것이다. 직접 메서드 호출을 막을 수 없기 때문에 생성자를 숨기는 것이 내가 할 수있는 최선책 인 것처럼 보였습니다. 이것은 확실히 내가 달성하려고하는 것과 인라인입니다. 도와 주셔서 감사합니다! – Krejko

+1

@Krejko Objective-C에는 생성자가 없습니다. 할당 메소드와 초기화 메소드가 있습니다. Pedantic, 확실하게, 그러나 일을 정확하게 설명하는 데 도움이됩니다. – bbum

+0

@bbum Duly가 언급했다. Android와 iOS간에 수신 거부가 발생했으며 용어가 섞이기 시작했습니다. – Krejko

0

앤드류 매드슨의 솔루션에 따르면, 나는 결국 각 개체에 대해 두 개의 서로 다른 헤더 파일을 사용하게되었다. 하나는 공개이고 다른 하나는 비공개였습니다. 공개 헤더에는 개발자가 읽기 전용 속성에 액세스하는 데 필요한 정보 만 들어 있습니다. 그런 다음 내 개인 헤더는 공개 헤더를 가져오고 SDK (초기화 프로그램 포함)에서 사용해야하는 모든 메소드 호출이 포함 된 카테고리도 포함합니다. 그런 다음 개인 헤더를 구현에 가져옵니다. 구조는 다음과 같습니다

공공 헤더 MyObject.h

#import <Foundation/Foundation.h> 

@interface MyObject : NSObject 
    @property (nonatomic, retain, readonly) NSString *myValue; 
@end 

개인 머리글을 MyObject + Private.h

#import "MyObject.h" 
@interface MyObject (Private) 
    +(MyObject*)MyObjectFromJSONString:(NSString*)JSONString; 
    -(id)initWithJSON:JSONString:(NSString*)JSONString 
@end 

개인 구현을 MyObject를.m

#import "MyObject+Private.h" 
@implementation MyObject 

@synthesize myValue = _myValue; //_myValue allows local access to readonly variable 

- (id)init { 
    @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"-init is not a valid initializer for the class MyObject" userInfo:nil]; 
    return nil; 
} 


+(MyObject*)MyObjectFromJSONString:(NSString*)JSONString; 
{ 
    return [[MyObject alloc]initWithJSON:JSONString]; 
} 


-(id)initWithJSON:JSONString:(NSString*)JSONString 
{ 
    self = [super init]; 
    if(self){ 
     //parse JSON 
     _myValue = JSONString; 
    } 
    return self; 
}