Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with extensions in Objective-C

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.

like image 951
hecate Avatar asked Mar 19 '17 02:03

hecate


1 Answers

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.

like image 180
fullofsquirrels Avatar answered Nov 09 '22 17:11

fullofsquirrels