Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

IDMah

macrumors 6502
Original poster
May 13, 2011
316
11
Hi all I got this to work but confused by other examples and if I am doing it correctly..

Code:
-(void)showWinAlert
{
    NSLog(@"gameTime was:%@",userScore.gameTime);
    
    NSMutableString *messageAlert = [[NSMutableString alloc]initWithFormat:
                                     @"with Time: %@",userScore.gameTime];
    // Testing alert //
    winAlert = [[UIAlertView alloc] initWithTitle:@"New High Score!!!" 
                                          message:messageAlert
                                         delegate:self
                                cancelButtonTitle:@"OK !"
                                otherButtonTitles:nil];
    
    // if High Score then //
    [winAlert setAlertViewStyle:UIAlertViewStylePlainTextInput];
    [winAlert textFieldAtIndex:0].keyboardAppearance = UIKeyboardAppearanceAlert;
    [winAlert  becomeFirstResponder];    
    [[winAlert textFieldAtIndex:0] setTextAlignment:UITextAlignmentCenter];
    [winAlert textFieldAtIndex:0].text=@"YourName";
    
    // hilight all the text in the field //
   
    // delegate the textfield in the Alert so we can limit size of input //
    UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
// **this is the confusing line. makes sense to me but.. 
    theTitleTextField.delegate = [winAlert delegate];

// ** most examples I found say this but this gives me an warning. 
// warning: Semantic Issue: Assigning to 'id<UITextFieldDelegate>' from incompatible type 'HighScoreViewControl'

    theTitleTextField.delegate = self; 

    [myTable reloadData];
    [winAlert show];
        
}
// then I do this //
// Limit textfield to MAXTEXT // 
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    if ([textField.text length] >= MAXLENGTH) {
        textField.text = [textField.text substringToIndex:MAXLENGTH-1];
        NSLog(@"calling Limit input");
        return NO;
    }
    return YES;
}

Like I said above works just wondering about the discrepancy between examples I found on web and what I need to do. Is it because the UIAlert is controller for the view and therefore I need to pass the textfield up through it, to self. Is there a better way to do this. will I run into any error later on doing it this way?

thanks
Ian
 

Sonnestah

macrumors regular
Mar 2, 2013
152
0
That makes indeed no sense, what it is doing is setting its delegate to self in a fancy weird way.

Just keep

Code:
theTitleTextField.delegate = self;

And that's it
 

devilofspades

macrumors member
Jul 20, 2011
76
0
Hi all I got this to work but confused by other examples and if I am doing it correctly..

Code:
-(void)showWinAlert
{
    NSLog(@"gameTime was:%@",userScore.gameTime);
    
    NSMutableString *messageAlert = [[NSMutableString alloc]initWithFormat:
                                     @"with Time: %@",userScore.gameTime];
    // Testing alert //
    winAlert = [[UIAlertView alloc] initWithTitle:@"New High Score!!!" 
                                          message:messageAlert
                                         delegate:self
                                cancelButtonTitle:@"OK !"
                                otherButtonTitles:nil];
    
    // if High Score then //
    [winAlert setAlertViewStyle:UIAlertViewStylePlainTextInput];
    [winAlert textFieldAtIndex:0].keyboardAppearance = UIKeyboardAppearanceAlert;
    [winAlert  becomeFirstResponder];    
    [[winAlert textFieldAtIndex:0] setTextAlignment:UITextAlignmentCenter];
    [winAlert textFieldAtIndex:0].text=@"YourName";
    
    // hilight all the text in the field //
   
    // delegate the textfield in the Alert so we can limit size of input //
    UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
// **this is the confusing line. makes sense to me but.. 
    theTitleTextField.delegate = [winAlert delegate];

// ** most examples I found say this but this gives me an warning. 
// warning: Semantic Issue: Assigning to 'id<UITextFieldDelegate>' from incompatible type 'HighScoreViewControl'

    theTitleTextField.delegate = self; 

    [myTable reloadData];
    [winAlert show];
        
}
// then I do this //
// Limit textfield to MAXTEXT // 
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    if ([textField.text length] >= MAXLENGTH) {
        textField.text = [textField.text substringToIndex:MAXLENGTH-1];
        NSLog(@"calling Limit input");
        return NO;
    }
    return YES;
}

Like I said above works just wondering about the discrepancy between examples I found on web and what I need to do. Is it because the UIAlert is controller for the view and therefore I need to pass the textfield up through it, to self. Is there a better way to do this. will I run into any error later on doing it this way?

thanks
Ian


this is your problem right here

Code:
    // delegate the textfield in the Alert so we can limit size of input //
    UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
// **this is the confusing line. makes sense to me but.. 
[B][U]theTitleTextField.delegate = [winAlert delegate];[/U][/B]
// ** most examples I found say this but this gives me an warning. 
// warning: Semantic Issue: Assigning to 'id<UITextFieldDelegate>' from incompatible type 'HighScoreViewControl'

    [B]theTitleTextField.delegate = self; [/B]

    [myTable reloadData];
    [winAlert show];

the line "theTitleTextField.delegate = [winAlert delegate];" is already setting the delegate to the winAlert's delegate, which is already "self". so there is no need for this line here "theTitleTextField.delegate = self;", so just remove it and that will fix your problem. also "delegate" is a property not a method (even though a hidden getter "-(id)delegate" method exists, which is why it works) it really should be "winAlert.delegate" not "[winAlert delegate]". it just makes for more "correct" code syntax.

"dot.syntax" is for properties.
"[square brackets]" are for methods.
 
Last edited:

IDMah

macrumors 6502
Original poster
May 13, 2011
316
11
Thanks for that clarification.. and note on syntax appreciated..
changed to:
Code:
UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
    theTitleTextField.delegate = winAlert.delegate;

I was just mentioning the:
Code:
theTitleTextField.delegate = self;
Line because it was what a few search result suggested, but not in my code.

thanks all
Ian
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
this is your problem right here

Code:
    // delegate the textfield in the Alert so we can limit size of input //
    UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
// **this is the confusing line. makes sense to me but.. 
[B][U]theTitleTextField.delegate = [winAlert delegate];[/U][/B]
// ** most examples I found say this but this gives me an warning. 
// warning: Semantic Issue: Assigning to 'id<UITextFieldDelegate>' from incompatible type 'HighScoreViewControl'

    [B]theTitleTextField.delegate = self; [/B]

    [myTable reloadData];
    [winAlert show];

the line "theTitleTextField.delegate = [winAlert delegate];" is already setting the delegate to the winAlert's delegate, which is already "self". so there is no need for this line here "theTitleTextField.delegate = self;", so just remove it and that will fix your problem. also "delegate" is a property not a method (even though a hidden getter "-(id)delegate" method exists, which is why it works) it really should be "winAlert.delegate" not "[winAlert delegate]". it just makes for more "correct" code syntax.

"dot.syntax" is for properties.
"[square brackets]" are for methods.


The dot syntax is entirely optional. I know plenty of developers who hate it and never use it under any circumstances.



Code:
winAlert.delegate
and
Code:
[winAlert delegate]

are both valid, and are interchangeable. The one thing that is not interchangeable about the two syntaxes is the handling of pointers of type "id" (anonymous object pointer type). The compiler allows you to send any message (method call syntax) to an id pointer without warning, but it will flag an error if you try to use the dot syntax if winAlert is type id.

The argument against do syntax is that it is syntactically ambiguous, and makes somebody else's code harder to understand.

If you see

someVariable.someField,

You can't tell from that expression if someVariable is an object, and someField is a property, or if someVariable is a C struct, and someField is a field in the structure. You have to go look up the definition of someVariable to tell which is the case.

Personally I like the dot syntax for properties and use it, but I dispute your "more correct" statement.
 

devilofspades

macrumors member
Jul 20, 2011
76
0
The dot syntax is entirely optional. I know plenty of developers who hate it and never use it under any circumstances.



Code:
winAlert.delegate
and
Code:
[winAlert delegate]

are both valid, and are interchangeable. The one thing that is not interchangeable about the two syntaxes is the handling of pointers of type "id" (anonymous object pointer type). The compiler allows you to send any message (method call syntax) to an id pointer without warning, but it will flag an error if you try to use the dot syntax if winAlert is type id.

The argument against do syntax is that it is syntactically ambiguous, and makes somebody else's code harder to understand.

If you see

someVariable.someField,

You can't tell from that expression if someVariable is an object, and someField is a property, or if someVariable is a C struct, and someField is a field in the structure. You have to go look up the definition of someVariable to tell which is the case.

Personally I like the dot syntax for properties and use it, but I dispute your "more correct" statement.

i would have to disagree. the only reason "it works" is because properties have a synthesized accessor getter method with the same name as the property. this is the same reason (in reverse) why "myArray.count" works, even though it should be "[myArray count]. "count" is a method and not a property of NSArray and should be treated as such. it just makes for better code consistency. to follow your stand point i could also start method names with capital letters, make class names starting with lowercase letters, etc. its all perfectly legal to do all these things, but it's just poor programming etiquette. that is the reason dot syntax exists in obj-c in the first place. as far as your comment about "id", the compiler allows you to do that because it has no idea what it is sending a message to because of the "blindness" of the process. the fact the compiler throws an warning is a good thing, and means you need to look at what it is you are doing and see if you can do it a different or "better" way. but just wrapping it in some "[ ]" to avoid an error is bad programming. but in this case "winAlert" is not of type "id", it's "delegate" is, and is a property which is why dot syntax works (as that's what it was designed for) and the code compiles just fine with no errors using "winAlert.delegate". i mean we both know in reality they are all "[messages calls]" under the hood, but for the sake of readability it is broke out like the way it is for a reason. my point on your "syntactically ambiguous" comment, would be it wouldn't and shouldn't make much difference either way. all things considered an object and it's properties are very similar to a struct (and probably is a struct under the hood) and can behave in similar ways. this is why dot syntax is used and the more reason to use it in such a way.
 
Last edited:

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
i would have to disagree. the only reason "it works" is because properties have a synthesized accessor getter method with the same name as the property. this is the same reason (in reverse) why "myArray.count" works, even though it should be "[myArray count]. "count" is a method and not a property of NSArray and should be treated as such. it just makes for better code consistency. to follow your stand point i could also start method names with capital letters, make class names starting with lowercase letters, etc. its all perfectly legal to do all these things, but it's just poor programming etiquette. that is the reason dot syntax exists in obj-c in the first place. as far as your comment about "id", the compiler allows you to do that because it has no idea what it is sending a message to because of the "blindness" of the process. the fact the compiler throws an warning is a good thing, and means you need to look at what it is you are doing and see if you can do it a different or "better" way. but just wrapping it in some "[ ]" to avoid an error is bad programming. but in this case "winAlert" is not of type "id", it's "delegate" is, and is a property which is why dot syntax works (as that's what it was designed for) and the code compiles just fine with no errors using "winAlert.delegate". i mean we both know in reality they are all "[messages calls]" under the hood, but for the sake of readability it is broke out like the way it is for a reason. my point on your "syntactically ambiguous" comment, would be it wouldn't and shouldn't make much difference either way. all things considered an object and it's properties are very similar to a struct (and probably is a struct under the hood) and can behave in similar ways. this is why dot syntax is used and the more reason to use it in such a way.


You are welcomed to your opinion. In fact, I use the same style that you do.

However, you are stating it as a firm coding guideline. It's not. The example of the use of upper and lower case in variable names and method names IS a well established coding convention in Cocoa/Cocoa Touch.

To quote the official Objective C 2.0 PDF (From Apple's website - can't find the link to it at the moment:)

Dot Syntax
Objective-C provides a dot (.) operator that offers a compact and convenient syntax you can use as an
alternative to square bracket notation
([]s) to invoke accessor methods. It is particularly useful when you
want to access or modify a property that is a property of another object (that is a property of another object,
and so on).
Using the Dot Syntax
Overview
You can use the dot syntax to invoke accessor methods using the same pattern as accessing structure
elements as illustrated in the following example:
myInstance.value = 10;
printf("myInstance value: %d", myInstance.value);
The dot syntax is purely “syntactic sugar”—it is transformed by the compiler into invocation of accessor
methods (so you are not actually accessing an instance variable directly). The code example above is exactly
equivalent to the following:
[myInstance setValue:10];
printf("myInstance value: %d", [myInstance value]);

And from this article which I did just find on Apple's site:


...Dot syntax is purely a convenient wrapper around accessor method calls. When you use dot syntax, the property is still accessed or changed using the getter and setter methods mentioned above...

That "purely a convenient wrapper" bit sure doesn't sound like a coding rule.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,751
8,423
A sea of green
... changed to:
Code:
UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
    theTitleTextField.delegate = winAlert.delegate;

I was just mentioning the:
Code:
theTitleTextField.delegate = self;
Line because it was what a few search result suggested, but not in my code.

Some of the following relies on guesswork, because you haven't posted the @interface for the class that contains the showWinAlert method.


First, consider this code:
Code:
theTitleTextField.delegate = self;
A possible reason it doesn't produce a warning is that the class containing the method is declared as implementing the UITextFieldDelegate protocol.

If you look at UITextField's delegate property you see this:
Code:
@property(nonatomic, assign) id<UITextFieldDelegate> delegate
This means the delegate can be any object type that implements the UITextFieldDelegate protocol. So if the class with the showWinAlert method implements that protocol, then the type of self in the assignment is a suitable type for the delegate.


Next, consider this code:
Code:
    theTitleTextField.delegate = winAlert.delegate;
The winAlert.delegate expression has whatever type is declared for the UIAlertView's delegate property.

Referring to the UIAlertView class reference, we see:
Code:
@property(nonatomic, assign) id delegate
with the note to "See UIAlertViewDelegate Protocol Reference for the methods this delegate should implement." So the delegate is declared as being a simple id type, but it's expected to implement methods from the UIAlertViewDelegate protocol.

When the delegate type is id, this isn't the same as id<UITextFieldDelegate>. You're assigning a less restrictive type (id) to a property that expects a more restrictive type (id<UITextFieldDelegate>), so the compiler warns you about this.

If the delegate type were id<UIAlertViewDelegate>, then you're still not assigning the expected type, which is id<UITextFieldDelegate>, so you'd still get a warning.

Whenever you see a compiler warning like this, start by asking yourself "What are the types involved?". You may have to dig into class references to find out exactly what types are expected, and what types are being returned. You'll also have to consider the type of self, i.e. what class the method is being defined in, what its superclass is, what protocols it implements, etc.


I won't venture a guess as to why the compiler warning mentioned 'HighScoreViewControl' without knowing what class the method is defined in.


(In the above, I've used the online class references to find the types used by each class's delegate property. Those docs may not be perfectly accurate or in sync with the headers in the SDK. Since the compiler reads headers, refer to those headers for the most accurate info on expected types.)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.