다음은 클래스 확장을 다루는 코드 조각입니다. 내가 뭘하려는 건 메모리에 암호화 된 형식으로 저장되어있는 내부 ID (나중에 프로그램에서 사용하는)라는 임의의 ID를 생성하는 것입니다. 이 코드는 gcc와 clang (Windows의 GNUStep을 통해 Objective C를 실행 중입니다)에서 코드의 주석으로 언급 된 각 컴파일러에 대해 다른 오류 메시지와 함께 컴파일되지 않습니다.Objective-C의 확장 기능과 관련된 문제
이 문제는 확장 프로그램 사용을 무시하고 기본 @interface (즉 # import 문 다음에 나오는 자체)에서 메소드와 속성을 선언함으로써 쉽게 해결할 수 있다는 사실을 알고 있습니다. 확장 기능을 사용하는 유일한 이유는이 클래스가 "internalID"속성에 액세스 할 수 없어야하는 몇 가지 하위 클래스에 상속된다는 것입니다. 사전에
#
# Command script for clang
# C:\GNUstep\msys\1.0\home\hecate\my\GNUmakefile
#
GNUSTEP_MAKEFILES=/GNUStep/System/Library/Makefiles
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = fwdORM
fwdORM_OBJC_FILES = fwdORM.m
fwdORM_OBJCFLAGS = -std=c99
# Implementation mixing Objective-C/CPP file going to be compiled; Currently not required
#fwdORM_OBJCC_FILES = fwdORM_21.mm
# Implementation CPP file going to be compiled; Currently N/A
#fwdORM_CC_FILES = sec_class_exec.cpp
# Header files of project
#fwdORM_HEADER_FILES = .h // N/A
# Define compilation flags
ADDITIONAL_CPPFLAGS = -Wall -Wno-import -fblocks
# Include rules for creating a command line tool for Objective-C
include $(GNUSTEP_MAKEFILES)/tool.make
감사 :
#import <Foundation/Foundation.h>
@interface Foo : NSObject
{
NSString * idStr;
}
- (void)setInternalID;
- (NSString *)fetchExternalID;
@end
// Extension declaration
@interface Foo()
{ // Compilation via gcc throws error at this line stating "Expected identifier or '(' before '{' token"
NSString *internalID; // Compilation via clang throws error at this line stating "instance variables may not be placed in class extension"
}
@end
@implementation Foo
- (void)setInternalID{
internalID = [NSString stringWithFormat:
@"__KEY__INTERNAL__DUMP2872167841398551___8765%d98KLPYFGF(&^$#ESFK___JNHGV",arc4random()%100];
}
- (NSString *)fetchExternalID{
NSString * externalID=[internalID stringByReplacingOccurrencesOfString:
@"__KEY__INTERNAL__DUMP2872167841398551___8765" withString:@""];
externalID=[externalID stringByReplacingOccurrencesOfString:
@"98KLPYFGF(&^$#ESFK___JNHGV" withString:@""];
return externalID;
}
@end
int main(int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Foo * bar = [[Foo alloc]init];
[bar setInternalID];
NSLog(@"External ID: %@",[bar fetchExternalID]);
[pool drain];
return 0;
}
내가 사용 GCC의 컴파일 문자열은 그 소리에 대해 다음과 같습니다 gcc -o _exec fwdORM.m -I /GNUstep/System/Library/Headers -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString
내 GNUmakefile '은 찾지입니다. 대신 바르의 클래스 확장에서 선언 된 @property
를 사용하여이를 구현
clang/Mac OS에서 오류를 재현 할 수 없습니다. 그러나 목표에 도달하려면'@ 구현 '에서 ivar을 정의하는 것이 좋습니다. –
@ AminNegm-Awad 이봐, 해결 방법을 좀 더 구체적으로 알려주시겠습니까? 왜냐하면 내가 아는 바에 따르면 모든 ivars는 '@interface'에 있어야하기 때문입니다. 그리고 clang/Mac OS에서 오류가 없다고 말하면 동일한 GNUmakefile을 구현 했습니까? 나는 코드가 Mac OS에서 컴파일되고 GNUStep/Windows에서 실패 할 수 있다고 생각하지 않는다. 늦게 답장을 보내 드려 죄송합니다. 나는 프로젝트의 다른 부분에 꽤 몰두했다. – hecate
아니, 나는 makefile없이 그것을했다. ivars가'@interface' 섹션에 정의되어야한다는 것은 사실이 아닙니다. '@ 구현'에서 똑같은 일을 할 수 있습니다. –