The following is a code snippet which deals with class extensions. What I am trying to do is generate a random ID called internal ID (that is used by the program later on) which is stored in an encrypted form in memory. The code fails to compile with both gcc and clang (I am running Objective C via GNUStep on Windows) with different error messages for each compiler which is mentioned as comments in the code.
Please note that I'm aware of the fact that this problem can be easily solved by disregarding the use of extensions and declaring methods and properties in the main @interface (i.e the one after the #import statement) itself. The only reason I'm going with extensions is that this class is inherited by a few other sub-classes to which the "internalID" property must be inaccessible.
#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;
}
The compilation string for gcc I'm using is gcc -o _exec fwdORM.m -I /GNUstep/System/Library/Headers -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString
My GNUmakefile for clang is as follows:
#
# 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
Thanks in advance.
Try implementing this by using a @property
declared in the class extension instead of an 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
This is standard semantics for what's effectively a private
variable, and probably stands a better chance of getting compiler support.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With