2017-03-19 13 views
8

次は、クラス拡張を扱うコードスニペットです。私がやろうとしているのは、メモリに暗号化された形式で格納されている内部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です。

+0

clang/Mac OSでエラーを再現することはできません。しかし、目標に到達するためには、 '@ implementation'でivarを定義する方が良いでしょう。 –

+0

@ AminNegm-Awadちょっと、それを解決するためのあなたの推奨された方法でもう少し具体的になることができますか?私が知っていることによると、すべてのivarsは '@interface'に配置されなければならないからです。そして、clang/Mac OSでエラーがないと言うと、同じGNUmakefileを実装しましたか?私はコードがMac OSでコンパイルでき、GNUStep/Windowsで失敗する可能性はないと思います。 遅く返事を申し訳ありません。私はかなりプロジェクトの別の部分に夢中でした:) – hecate

+0

いいえ、私はmakefileなしでそれをしました。 ivarsは '@interface'セクションで定義しなければなりません。 '@ implementation'でも同じことができます。 –

答えて

4

ではなく、IVARのクラスの拡張で宣言さ@propertyを使用してこれを実装してみてください。

#import <Foundation/Foundation.h> 

@interface Foo : NSObject 
- (void)setInternalID; 
- (NSString *)fetchExternalID; 
@end 

// Extension declaration 
@interface Foo() 
@property (strong) NSString *internalID; 
@end 

@implementation Foo 

- (void)setInternalID { 
    self.internalID = [NSString stringWithFormat:@"__KEY__INTERNAL__DUMP2872167841398551___8765%d98KLPYFGF(&^$#ESFK___JNHGV",arc4random()%100]; 
} 

- (NSString *)fetchExternalID { 
    NSString * externalID = [self.internalID stringByReplacingOccurrencesOfString:@"__KEY__INTERNAL__DUMP2872167841398551___8765" withString:@""]; 
    externalID = [externalID stringByReplacingOccurrencesOfString:@"98KLPYFGF(&^$#ESFK___JNHGV" withString:@""]; 
    return externalID; 
} 

@end 

これは効果的private変数だ何のための標準的な意味論で、おそらくコンパイラのサポートを得るための良いチャンスを立っています。

関連する問題