Objective-C 中的扩展问题
Issue with extensions in Objective-C
以下是处理 class 扩展的代码片段。我想做的是生成一个随机 ID,称为内部 ID(稍后由程序使用),它以加密形式存储在内存中。该代码无法用 gcc 和 clang 编译(我是 运行 Objective C 通过 GNUStep on Windows),每个编译器都有不同的错误消息,在代码中作为注释提到。
请注意,我知道这个问题可以通过忽略扩展的使用并在主@interface(即#import 语句之后的接口)本身中声明方法和属性来轻松解决。我使用扩展的唯一原因是这个 class 被其他一些子 class 继承,其中 "internalID" 属性 必须是不可访问的。
#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
我的 clang 的 GNUmakefile 如下:
#
# Command script for clang
# C:\GNUstep\msys.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
提前致谢。
尝试使用 class 扩展中声明的 @property
而不是 ivar 来实现:
#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
变量的标准语义,可能更有可能获得编译器支持。
以下是处理 class 扩展的代码片段。我想做的是生成一个随机 ID,称为内部 ID(稍后由程序使用),它以加密形式存储在内存中。该代码无法用 gcc 和 clang 编译(我是 运行 Objective C 通过 GNUStep on Windows),每个编译器都有不同的错误消息,在代码中作为注释提到。
请注意,我知道这个问题可以通过忽略扩展的使用并在主@interface(即#import 语句之后的接口)本身中声明方法和属性来轻松解决。我使用扩展的唯一原因是这个 class 被其他一些子 class 继承,其中 "internalID" 属性 必须是不可访问的。
#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
我的 clang 的 GNUmakefile 如下:
#
# Command script for clang
# C:\GNUstep\msys.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
提前致谢。
尝试使用 class 扩展中声明的 @property
而不是 ivar 来实现:
#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
变量的标准语义,可能更有可能获得编译器支持。