views:

242

answers:

5

I am very familiar with writing VB based applications but am new to Xcode (and Objective C). I have gone through numerous tutorials on the web and understand the basics and how to interact with Interface Builder etc. However, I am really struggling with some basic concepts of the C language and would be grateful for any help you can offer. Heres my problem…

I have a simple iphone app which has a view controller (FirstViewController) and a subview (SecondViewController) with associated header and class files.

In the FirstViewController.m have a function defined

@implementation FirstViewController

- (void) writeToServer:(const uint8_t *) buf {
    [oStream write:buf maxLength:strlen((char*)buf)];   
}

It doesn't really matter what the function is.

I want to use this function in my SecondViewController, so in SecondViewController.m I import FirstViewController.h

#import "SecondViewController.h"
#import "FirstViewController.h"

@implementation SecondViewController

-(IBAction) SetButton: (id) sender {
    NSString *s = [@"Fill:" stringByAppendingString: FillLevelValue.text];
    NSString *strToSend = [s stringByAppendingString: @":"];
    const uint8_t *str = (uint8_t *) [strToSend cStringUsingEncoding:NSASCIIStringEncoding];
    FillLevelValue.text = strToSend;

    [FirstViewController writeToServer:str];
}

This last line is where my problem is. XCode tells me that FirstViewController may not respond to writeToServer. And when I try to run the application it crashes when this function is called.

I guess I don't fully understand how to share functions and more importantly, the relationship between classes.

In an ideal world I would create a global class to place my functions in and call them as required.

Any advice gratefully received.

A: 

You need to write:

- (void) writeToServer:(const uint8_t *) buf;

in your FirstViewController.h file. This is a hint for the compiler that the function is available for that particular class. Your code would still work without this, because the actual function is implemented, but you get the warning because the compiler doesn't check the .m file for existing functions when you include the header from another source file.

MihaiD
A: 

In the deklaration of your method:

- (void) writeToServer:(const uint8_t *) buf;

The - at the beginning of the declaration indicates, that it is an instant method. This means, you have to create an instance of your class to call it. If there were a +, the method would be a class method and you could call it the way you do in your code.

Example:

@interface MyClass
{ }
 - (void) myInstanceMethod;
 + (void) myClassMethod;
@end

Then in some function:

[MyClass myClassMethod]; // This is ok

//[MyClass myInstanceMethod]; // this doenst't work, you need an instance:

MyClass *theInstance = [[MyClass alloc] init];
[theInstance myInstanceMethod];
gammelgul
A: 

if you want to call this method like this only declare writeToServer method as class method (static method in short...)

for that you have declare and define it like

+ (void) writeToServer:(const uint8_t *) buf;

+ (void) writeToServer:(const uint8_t *) buf {
    [oStream write:buf maxLength:strlen((char*)buf)];   
}

only difference is + sign instead of -

  • sign indicate that method is class method(static) and - sign is for instance method (non static)

Second option is creat instance of FirstViewController and call the existing method

i.e

FirstViewController FirstViewControllerObj = [[FirstViewController alloc] init];
 [FirstViewControllerObj writeToServer:str];
mihirpmehta
Thanks for the replies i have tried both methods now but can't seem to get any of them to work i keep getting the following errorsbelow SummaryViewController SummaryViewControllerObj = [[SummaryViewController alloc] init];error:Variable-sized object may not be initializederror:statically allocated instance of object-c class 'SummaryViewController'error:statically allocated instance of object-c class 'SummaryViewController'and below [summaryViewControllerObj writeToServer:str];warning:'SummaryViewController' may not respond to '-writeToServer:'error:cannot convert to pointer type
Guy Parker
A: 
  1. In your FirstViewController.h file, you must declare writeToServer as a method of FirstViewController object in the @interface section

    @interface FirstViewController : UIViewController { }

    • (void) writeToServer:(NSString *) str;

    @end

  2. Secondly, the following message you send is invalid as FirstViewController writeToServer is not a class method and is only valid if called from an instantiation of the FirstViewController class.

    FirstViewController *firstViewCnt = [[FirstViewController alloc] init]; [firstViewCnt writeToServer:str]; [firstViewCnt release];

Or something like that.

Kenny
+1  A: 

In the line:

[FirstViewController writeToServer:str];

...you are sending the message writeToServer: to the FirstViewController class. Instead, you need to send it to a FirstViewController object. This means that you need to obtain a reference to a FirstViewController object and then send the object the writeToServer: message:

[firstViewControllerObject writeToServer:str];

However, because there is only one view active at a time on the iPhone, you should not be having FirstViewController and SecondViewController objects existing at the same time and communicating with each other. Instead, you should create independent classes to perform the required class and the active view controller should be interacting with these classes.

Note: "You are sending the message sayHello: to the object myObject" is just another way of saying "you are calling the writeToServer: method of the object myObject. (A "method" is like the object-oriented version of a function.)

I would recommend reading the Learning Objective-C and Learn Cocoa II tutorials on Cocoa Dev Central to learn more about Cocoa/Objective-C and object-oriented programming.

Steve Harrison