DroidHeaven
DroidHeaven

Reputation: 2464

Implicit conversion of a non-Objective-C pointer type 'int *' to 'Bird *' is disallowed with ARC

Bird, GameWorld and GameScene are three custom classes in my project.

I've an object of type Bird(as a property) in the class Gameworld. I've objects of type Bird and Gameworld in the class GameScene. Now in Gamescene class, when I do:

_bird = [_gameWorld bird];

an error is alerted:

Implicit conversion of a non-Objective-C pointer type 'int *' to 'Bird *' is disallowed with ARC

Why this is happening?

Edit:

GameScene.h

#import <SpriteKit/SpriteKit.h>
#import "Bird.h"
#import "ScrollHandler.h"
#import "Pipe.h"
#import "GameWorld.h"

@interface GameScene : SKScene <SKPhysicsContactDelegate>{

    int _midPointY;
    float _gameHeight;
    NSString *_gameName;
    NSString *_getReady;
    Bird *_myBird;   

    NSTimeInterval _dt;
    float bottomScrollerHeight;

    GameWorld *_myWorld;   

}

@property (nonatomic) SKSpriteNode* backgroundImageNode;
@property (nonatomic) SKSpriteNode* greenBird;

@property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;


@end

GameWorld.h

#import <Foundation/Foundation.h>
#import <SpriteKit/SpriteKit.h>
#import "Bird.h"
#import "ScrollHandler.h"

typedef NS_ENUM(NSInteger, GameState){
    MENU,
    READY,
    RUNNING,
    GAMEOVER,
    HIGHSCORE
};

@interface GameWorld : NSObject <ScrollHandlerDelegate>{

    float _runTime;
    GameState _currentState;

}

@property (nonatomic, strong) ScrollHandler *scroller;
@property (nonatomic, strong) Bird *bird;
@property (nonatomic, assign) int midPointY;
@property (nonatomic, assign) int score;
@property (nonatomic, strong) SKSpriteNode *bg;
@property (nonatomic, strong) NSArray *birds;
@property (nonatomic, strong) SKSpriteNode *birdNode; 

@end

GameScene.m

#import "GameScene.h"


#define UPWARD_PILLER @"Upward_Green_Pipe"
#define Downward_PILLER @"Downward_Green_Pipe"

static const uint32_t pillerCategory            =  0x1 << 0;
static const uint32_t birdCategory        =  0x1 << 1;
static const uint32_t grassCategory             =  0x1 << 2;


static const float BG_VELOCITY = (TIME * 60);

static inline CGPoint CGPointAdd(const CGPoint a, const CGPoint b)
{
    return CGPointMake(a.x + b.x, a.y + b.y);
}

static inline CGPoint CGPointMultiplyScalar(const CGPoint a, const CGFloat b)
{
    return CGPointMake(a.x * b, a.y * b);
}



@implementation GameScene

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {       

        self.anchorPoint = CGPointMake(0, 1);
        self.yScale = -1;

        //To detect collision detection
        self.physicsWorld.contactDelegate = self;
        _myWorld = [[GameWorld alloc] initWithMidPointY:_midPointY];
        [self initGameObjects];
        [self initAssets];
        [self setCoinAnimation];
    }
    return self;
}

-(void) initGameObjects {

    _myBird = [_myWorld bird]; //here is the problem

}

-(void) initAssets {

    //initialize other assets

}

-(void) setCoinAnimation {

    //initialize other assets

}

@end

Bird.h

#import "GameWorld.h"

@import UIKit;

@interface Bird : NSObject {

    CGPoint _position;
    CGPoint _velocity;
    CGPoint _acceleration;

    float _rotation;
    float _originalY;
    int _width;
    int _height;
    int _dieCount;
    bool _isAlive;    

}

@end

Note:I just found out that when I remove the import "Gameworld.h" from "Bird.h", the error disappears and it is working. The import was made there accidentally and it is not needed. But I don't why it caused the error.

Upvotes: 0

Views: 3120

Answers (2)

Jeffery Thomas
Jeffery Thomas

Reputation: 42588

Import statements must be linear, but you had a loop. GameScene.m -> GameScene.h -> Bird.h -> GameWorld.h -> Bird.h.

Because of this, when GameWorld.h had #import "Bird.h", the compiler saw that Bird.h was already imported and didn't import it. The problem was @interface Bird had not been defined yet, so GameWorld didn't have the proper interface for Bird.

Upvotes: 2

Burhanuddin Sunelwala
Burhanuddin Sunelwala

Reputation: 5343

Well as you mentioned in the end, thats was the only issue.

So what was happening?

When you imported Gameworld to your Bird interface file, in that, your Gameworld itself had a variable named bird which was of type Bird. You then went ahead and defined the Bird class in the subsequent lines. Before that the compiler din't knew what the Bird object is and it by default assumes it as int.

If you any how want to to declare Gameworld object in your Bird class, then instead of importing it your interface, you just need to use forward declaration, i.e.

@class Gameworld;

This tells the compiler that a Class do exist with the name Gameworld.

Upvotes: 1

Related Questions