1

Hopefully not a ridiculous question as I'm a self taught programmer, but I found some code which looked like it might help me do something I wanted to. Basically I want to enhance the NSLog() function in one of my apps, and would like to call my method in the same way as NSLog(). It's very difficult to google 'void function()' because nothing seems to be relevant, I'm used to methods that are constructed like this:

-(void)RLog(NSString*)statement;

But the sample suggested using:

void RLog(NSString *statement,...);

This seems to work, and lets me call it with 'RLog(@"My message")', however using it this way the method ignores the class variables, and seems I can't use 'self' either ...

Logging.h

#import <UIKit/UIKit.h>
@import Foundation.NSString;

@interface Logging : NSObject

@property (nonatomic) BOOL enabled;

void RLog(NSString *statement,...);

@end

Logging.m

#import "Logging.h"

@implementation Logging

@synthesize enabled;

void RLog(NSString *format,...) {

     /* something that uses 'enabled' throws 'Use of undeclared identifier enabled' */

     /* something else that uses '[[self class] session]' throws 'Use of undeclared identifier self' */

}

@end

Hopefully I've included enough information to explain my issue, and not removed too much to make it hard to understand!

Thanks in advance.

Plasma

Plasma
  • 2,622
  • 2
  • 20
  • 35

2 Answers2

1
void RLog(NSString *format,...)

... is not an Objective-C method; it's just a C function.

C functions are global and free-standing. There is no self here and no connection with Logging's enabled. As far as this function is concerned, the Logging class might as well not exist at all.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Right ok, so if I want it to be conditional I need to send the condition in when I call it? I'm not familiar with plain C. I would like to be able to call this and have it behave differently based upon a boolean value, which I would prefer not to pass in. – Plasma Dec 13 '20 at 23:49
  • Yes, that's how C functions are. Take a look at any C function in Cocoa, you have to send _everything_ in. (For example, https://developer.apple.com/documentation/coregraphics/1455939-cgbitmapcontextcreate.) You could pass a Logging object _into_ the function, if it is full of properties that you need, but the C function is not "inside" the Logging object in any sense. – matt Dec 14 '20 at 00:39
1

After a bit more investigation I found a way around this using the information here.

I added a class variable called thisClass and then assigned 'self' to it during my class init stage.

@implementation Logging
    
id  thisClass;

- (id) init
{
    if (self = [super init])
    {
        thisClass = self;
    }
    return self;
}

From inside the C function I can now call methods in my Logging class using:

[thisClass log:@"Testing"];

Without having to send "self" in as a parameter, I've moved the rest of the code which needs the local variables in to my 'log' method and simply use the C method to call it in a simplified way.

Plasma

Plasma
  • 2,622
  • 2
  • 20
  • 35