-1

When i am Building this code i am getting WARNING that INVALID Integer to pointer conversion. But when I run the application it gets Crash .....

can any one help me... I am getting warning at withObject:[sender tag]

i have frontButtonScaleUp Method which takes (NSIngeter) argument... and also tag returns NSInteger value...

- (IBAction)frontButtonReleased:(id)sender
{
    const double delay = 0.3;
    double elapsed = CACurrentMediaTime() - tapStartTime;;
    if (elapsed >= delay)
        [self frontButtonScaleUp:[sender tag]];
    else
        [self performSelector:@selector(frontButtonScaleUp) withObject:[sender tag] afterDelay:delay - elapsed];
}
DShah
  • 9,768
  • 11
  • 71
  • 127

4 Answers4

5

[sender tag] is an NSInteger and you cannot pass it to performSelector:withObject:afterDelay: as it expects an object there. What you can do is call the function like this:

[self performSelector:@selector(frontButtonScaleUp) withObject:[NSNumber numberWithInt:[sender tag]] afterDelay:delay - elapsed];

or try

[self performSelector:@selector(frontButtonScaleUp) withObject:(id)[sender tag] afterDelay:delay - elapsed];

I'm not sure of any of them but please let me know if that works.

Mihai Fratu
  • 7,579
  • 2
  • 37
  • 63
  • +1 to the first answer, -1 to the second one; you don't know if the framework will call `retain` on your object (which if it's just an int will fail horribly!) – deanWombourne Jul 22 '11 at 11:33
  • Both of the solutions i have tried though i dont get warnings but in first situation application crashes.... and in second situation i got EXC_BAD_EXECUTION error.... – DShah Jul 22 '11 at 11:36
  • Hello Praveen, First one just crashes my application .... can you give me another solution.... – DShah Jul 22 '11 at 11:37
  • You cand change your `frontButtonScaleUp:` function to receive an `NSNumber`. It shouldn't crash after that. Just be aware to also change the other line of code to `[self frontButtonScaleUp:[NSNumber numberWithInt:[sender tag]]];`. Then in your function's body you can take the integer value from the argument like this: `NSInteger intValue = [functionArgument integerValue];`. – Mihai Fratu Jul 22 '11 at 11:59
  • I tried this also and as soon as i change the .h file - (void)frontButtonScaleUp: (NSNumber) tag; i am getting error "Interface type NSNumber cannot be passed by value." – DShah Jul 22 '11 at 12:04
  • And it doesn't work? It cannot be - are you sure sender is still 'alive' when you are trying to access the tag method? Where and what's the crash message that you are getting? – Mihai Fratu Jul 22 '11 at 12:06
0

You will not be able get the tag of button as you did in your code. Do it like this to get the button and then use it, your problem will be solved

- (IBAction)frontButtonReleased:(id)sender
{

UIButton *button = (UIButton *)sender;
        int Btag = button.tag;

const double delay = 0.3;
double elapsed = CACurrentMediaTime() - tapStartTime;;
if (elapsed >= delay)
    [self frontButtonScaleUp:Btag];
else
    [self performSelector:@selector(frontButtonScaleUp) withObject:Btag afterDelay:delay - elapsed];
}
  • I have used same code as u have given but still i am getting warning at withObject : Incompatible integer to pointer conversion sending 'int' to parameter of type 'id'... Can any one tell me what should i pass in withObject...??????? – DShah Jul 22 '11 at 12:33
  • 1
    Use data type 'id' instead of int and then use it as; id Btag = button.tag; – Mobile Developer iOS Android Jul 22 '11 at 12:37
0

Hmmm, without knowing what your method frontButtonScaleUp does, I cannot give a definitive answer, but I can tell you this - the tag attribute of an NSView is a simple int with no gaurantee of being a useful value. It is a convenience attribute on the class, given to developers to use pretty much however they want. In no way shape or form should this attribute be ever confused with a pointer!

On this line of code:

if (elapsed >= delay) 
    [self frontButtonScaleUp:[sender tag]];

I can't really comment because like I said, I don't know what the definition or implementation of frontButtonScaleUp is. But I am guessing you are expecting an id of some sort and passing in an int instead. Your code will almost assuredly blow up here, if your unlucky it will do so at random.

This line:

else 
    [self performSelector:@selector(frontButtonScaleUp) withObject:[sender tag afterDelay:delay - elapsed];

Is definitely wrong - once again, int != id.

Im guessing that you are trying to increase the size of a button after its been tapped, after a certain delay? You already have the id of the button, it's the sender parameter into your function. Just pass that into your frontButtonScaleUp method and you should get past your compiler warning and *EXC_BAD_ACCESS* exception.

if (elapsed >= delay) 
    [self frontButtonScaleUp:[sender]];
Perception
  • 79,279
  • 19
  • 185
  • 195
  • Yes, i want to increase the size of the button. So my frontButtonScaleUp takes the reference of the button and then i using simple code which works on different project... but here i want 2 buttons to use same code.. thats why i am using sender instead of button reference directly... – DShah Jul 22 '11 at 15:55
  • @Dhiren Shah - thats what I thought. Have you tried the code from my answer? You should be able to just pass *sender* instead of *[sender tag]* and your function will work. – Perception Jul 22 '11 at 16:00
  • I have tried with Sender also but when my code goes into else part.... my app gets crash... just because of withObjects... – DShah Jul 22 '11 at 16:38
  • @Dhiren Shah - please modify your original question with both the crash you get (when you use *sender* as opposed to *[sender tag]*), and the implementation of ***frontButtonScaleUp***. – Perception Jul 22 '11 at 17:37
-1

I have made work my code with little modifications like below:

- (IBAction)frontButtonReleased:(id)sender
{
    const double delay = 0.4;
    double elapsed = CACurrentMediaTime() - tapStartTime;;
    UIButton *btn = (UIButton *)sender;

    if (isBtnOneTurnOver || isBtnTwoTurnOver)
    {
        if ([btn tag] == 1)
        {
            if (elapsed >= delay)
                [self btnOneScaleUp];
            else
                [self performSelector:@selector(btnOneScaleUp) withObject:nil afterDelay:(delay - elapsed)];
        }
        else
        {
            if (elapsed >= delay)
                [self btnTwoScaleUp];
            else
                [self performSelector:@selector(btnTwoScaleUp) withObject:nil afterDelay:(delay - elapsed)];
        }
    }
}

here i have made two new methods for each button and both having no arguments so... that the problem of passing withObject was solved....

DShah
  • 9,768
  • 11
  • 71
  • 127