Method not recognized

Hi,

I am stuck and can’t seem to find a way out. I am able to create an instance of BNRPortfolio but this instance doesn’t recognize my custom methods like “addStock”. I hope somebody can help me. I am new to OS X programming and find the book very good so far.

Here is my code of BNRPortfolio.m:

#import "BNRPortfolio.h"
#import "BNRStockHolding.h"

@implementation BNRPortfolio

- (double)currentValue:(BNRStockHolding *)holding
{
    return [holding valueInDollars] - [holding costInDollars];
}

- (void)addStock:(BNRStockHolding *)s
{
    // Do we have an array?
    if (!_portfolios) {
        // If not, create one
        _portfolios = [[NSMutableArray alloc]init];
    }
    [_portfolios addObject:s];
}
@end

BNRPortfolio.:

#import <Foundation/Foundation.h>
@class BNRStockHolding;

@interface BNRPortfolio : NSObject

{
    NSMutableArray *_portfolios;
}

@property (nonatomic) double currentValue;
- (void)addStock:(BNRStockHolding *)s;

@end

Main:

#import <Foundation/Foundation.h>
#import "BNRStockHolding.h"
#import "BNRForeignStockHolding.h"
#import "BNRPortfolio.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        BNRStockHolding *holding1 = [[BNRStockHolding alloc] init];
        BNRStockHolding *holding2 = [[BNRStockHolding alloc] init];
        BNRStockHolding *holding3 = [[BNRStockHolding alloc] init];
        
        // Child Object of BNRStockHolding
        BNRForeignStockHolding *holding4 = [[BNRForeignStockHolding alloc] init];
        
        [holding1 setPurchaseSharePrice:2.30];
        [holding1 setCurrentSharePrice:4.50];
        [holding1 setNumberOfShares:40];
        [holding1 setNameOfHolding:@"holding1"];
        

        [holding2 setPurchaseSharePrice:12.19];
        [holding2 setCurrentSharePrice:10.55];
        [holding2 setNumberOfShares:90];
        [holding2 setNameOfHolding:@"holding2"];
        
        [holding3 setPurchaseSharePrice:45.10];
        [holding3 setCurrentSharePrice:49.51];
        [holding3 setNumberOfShares:210];
        [holding3 setNameOfHolding:@"holding3"];
        
        // Same values as holding1 but different outcome because the method is overriden and calculates Euro in Dollar
        [holding4 setPurchaseSharePrice:2.30];
        [holding4 setCurrentSharePrice:4.50];
        [holding4 setNumberOfShares:40];
        [holding4 setNameOfHolding:@"holding4"];
        
        
        
        
        NSArray *allHoldings = @[holding1, holding2, holding3, holding4];
        
        
        for (BNRStockHolding *a in allHoldings){
            NSLog(@"%@", a); // prints custom description of a holding made by me in BNRStockHolding.h
        }
        
        BNRPortfolio *portfolio = [[BNRPortfolio alloc] init];
        [portfolio addStock]; // NOT RECOGNIZED
        
    }
    return 0;
}

I get the message: No visible @interface for “BNRPortfolio” declares the selector “addStock”

But I importert the header files and also I can create an instance of BNRPortfolio. Thanks in advance!

I can’t see anything wrong with your code; it builds without any errors.

Did you actually have the addStock: method declared in BNRPortfolio’s interface at the the time you had that error?

It could also be that you had something unusual with your project settings.

Hi Ibex,

thanks for your answer. I didn’t have and still don’t have an addObject method declared. My code looks exactly like the code I posted and everything else runs without problems. I already struggle a day with this and don’t want just to copy/paste a solution but want to find the problem so that next time I can find the solution much quicker :slight_smile:

Do you have any more ideas? Why is that, that I can create a BNRPortfolio object but can’t access it’s method?

P.S. can you create a BNRPortfolio object with my code? Because you said it builds without any errors. I still can’t so maybe the issue lays on another place (but I can build without creating that object).

Oops! That should be addStock: not addObject:

Here is your code, but because I did not have the code for BNRStockHolding, I had to improvise:

//  BNRPortfolio.h

#import <Foundation/Foundation.h>

@class BNRStockHolding;

@interface BNRPortfolio : NSObject
{
    NSMutableArray *_portfolios;
}

@property (nonatomic) double currentValue;

# if 0   // exclude this method to simulate No visible @interface for ... error
         // change 0 to 1 to include
- (void)addStock:(BNRStockHolding *)s;
#endif

@end
//  BNRPortfolio.m

#import "BNRPortfolio.h"

@implementation BNRPortfolio

- (double)currentValue:(BNRStockHolding *)holding
{
    return 0;
}

- (void)addStock:(BNRStockHolding *)s
{
    // Do we have an array?
    if (!_portfolios) {
        // If not, create one
        _portfolios = [[NSMutableArray alloc]init];
    }
    [_portfolios addObject:s];
}
@end
//  main.m

#import <Foundation/Foundation.h>
#import "BNRPortfolio.h"

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        BNRPortfolio *portfolio = [[BNRPortfolio alloc] init];
        [portfolio addStock:[NSNull null]];
    }
    return 0;
}

Try experimenting with the # if 0 … #endif in BNRPortfolio.h

Thank your for your fast support Ibex.

It’s not only the addStock method but also the currentValue method which I can’t access and they are both declared in the interface of BNRPortfolio.

How can I use the #if#endif ? what does it do? -> excuse me for my newbie questions :slight_smile:. In the past I only programmed some Java.
I guess to does, like your comments are saying, exclude the declaration, so it would be the same as commenting out right?

I tried exactly what you wrote but still and implemented [portfolio addStock:[NSNull null]]; in the main.m but still no change

Here is my code from BNRStockHolding:

#import <Foundation/Foundation.h>

@interface BNRStockHolding : NSObject

@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) unsigned int numberOfShares;
@property (nonatomic) NSString *nameOfHolding;


// Methods
- (float)costInDollars;
- (float)valueInDollars;


@end
#import "BNRStockHolding.h"

@implementation BNRStockHolding


// Calculation with with get methods


- (float)costInDollars
{
    return [self purchaseSharePrice] * [self numberOfShares];
}

- (float)valueInDollars
{
    return [self currentSharePrice] * [self numberOfShares];
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"\n Holding Name: %@\n Cost in Dollars: %.2f\n Value in Dollars: %.2f\n",
            self.nameOfHolding, self.costInDollars, self.valueInDollars];
}

@end

After researching I finally found the solution.

Somehow Xcode had two .h files in the project folder. I had to select the newer one with Xcode manually and now everything builds up!

Thanks for your support Ibex!