isEqualToString always returns true - objective-c

for (Annotation *ann in annotaionArray) // annotationArray contains annotations added to map
{
NSString *fetchedtitle = ann.title;
if([fetchedtitle isEqualToString:oldTitle]); // oldTitle = textfield.text
{
ann.title = appDelegate.pinTitle;
break;
}
}
But the comparison is always true. What could be the error please?
fetched const char from sqlite is casted to stringWithUTF8String.
Everything has been done to cast perfectly to string but still why is the error in comparison?

Remove the trailing semi-colon!
if ([fetchedtitle isEqualToString:oldTitle])
{
ann.title = appDelegate.pinTitle;
break;
}
With the semi-colon, your code is the same as:
if ([fetchedtitle isEqualToString:oldTitle])
;
{
ann.title = appDelegate.pinTitle;
break;
}

Since you have a semi colon at the end of your IF statement your code is :
if( [fetchedtitle isEqualToString:oldTitle])
{
// Do nothing
}
// this will always run
ann.title = appDelegate.pinTitle;
break;

replace the following line
if([fetchedtitle isEqualToString:oldTitle]);
with
if([fetchedtitle isEqualToString:oldTitle])

Just remove semicolon(;) from the following part of your code...
if([fetchedtitle isEqualToString:oldTitle]);

Related

How to accept multiple enum types for one method parameter

I saw several questions on this problem, but none about iOS.
I have two enums like following :
// My first enum eColor
typedef enum
{
eColorRed = 1,
eColorGreen,
eColorBlue
} eColor;
// My second enum eShape
typedef enum
{
eShapeCircle = 1,
eShapeSquare,
eRectangle
} eShape;
I would like to have a method which accept both of these enums like this :
+ (NSString*) toStr:(bothEnum)e
{
NSString *result = nil;
if (bothEnum == eColor)
{
switch(e) {
case eColorRed:
result = #"red";
break;
case eColorGreen:
result = #"green";
break;
case eColorBlue:
result = #"blue";
break;
default:
result = #"unknown";
}
}
else if (bothEnum == eShape)
{
switch (e) {
case eShapeCircle:
result = #"circle";
break;
case eShapeSquare:
result = #"square";
break;
case eShapeRectangle:
result = #"rectangle";
break;
default:
result = #"unknown";
}
}
return result;
}
Is a thing like this possible ?
I don't want to have methods like colorToStr:, shapeToStr:, etc. My wish is to have only one method called toStr:, as above...
Enums are just constants and at run time they are just numbers. So your method doesn't know what is eColorRed, it knows it as 1, and your only option is to pass additional parameter, telling your method wether 1 passed in first argument is eColorRed or eShapeCircle. It can be just a string, like:
+ (NSString*) toStr:(NSUInteger)e fromEnumType:(NSString*)type
{
if([type isEqualToString:#"eColor"])
{
switch(e)
...
}
else if([type isEqualToString:#"eShape"])
{
switch(e)
...
}
}
You may try this approach: You make the second enum to start indexing from the last index of the first enum, then you just use single witch in your method. Remember enum type is just an int type indeed.
// My first enum
typedef enum
{
eColorRed = 1,
eColorGreen,
eColorBlue,
eColorLastIndex
} eColor;
// My second enum
typedef enum
{
eShapeCircle = eColorLastIndex,
eShapeSquare,
eShapeRectangle,
} eShape;
typedef int eTypes;
+(NSString*)toStr:(eTypes)e
{
NSString *result = nil;
switch(e) {
case eColorRed:
result = #"red";
break;
case eColorGreen:
result = #"green";
break;
case eColorBlue:
result = #"blue";
break;
case eShapeCircle:
result = #"circle";
break;
case eShapeSquare:
result = #"square";
break;
case eShapeRectangle:
result = #"rectangle";
break;
default:
result = #"unknown";
break;
}
return result;
}
Instead eGraphics you may use just int or eColorShape, whatever.
Update for 64-bit Change:
According to apple docs about 64-bit changes,
Enumerations Are Also Typed : In the LLVM compiler, enumerated types can
define the size of the enumeration. This means that some enumerated
types may also have a size that is larger than you expect. The
solution, as in all the other cases, is to make no assumptions about a
data type’s size. Instead, assign any enumerated values to a variable
with the proper data type
So you have to create enumeration with type as below syntax if you support for 64-bit.
typedef enum eColor : NSUInteger {
eColorRed = 1,
eColorGreen,
eColorBlue
} eColor;
then go with #user2260054's answer, otherwise, it will lead with below warning in 64-bit environment.
Otherwise, it will lead to warning as Implicit conversion loses integer precision: 'NSUInteger' (aka 'unsigned long') to eColor
This is not good for design point of view. Cohesion is broken over here. While programming OOP concept must be implemented for reuse of code and decoupling the objects as well.

Conditional Statement checking length of string

I'm trying to create a conditional statement that returns to me "nothing entered" if the string length is less than 1. However, I'm getting an error message in xcode that says: Expected identifier. I think my syntax may be wrong but I can't figure it out.
- (IBAction)batman:(id)sender {
if ([self.nameTextField.text.length] < 1)
{ //returnType method argument
[NSString stringWithFormat:#"nothing entered."];
}
else {
self.secondLabel.text = [NSString stringWithFormat:#"Batman %#", self.nameTextField.text ];
}
}
Just get rid of your brackets [] and it should work:
- (IBAction)batman:(id)sender {
if (self.nameTextField.text.length < 1) {
self.secondLabel.text = #"nothing entered.";
} else {
self.secondLabel.text = [NSString stringWithFormat:#"Batman %#", self.nameTextField.text ];
}
}

Uncrustify: Trim linebreaks before braces

What is the right config for uncrustify so that it removes empty lines before curly braces so that:
}
}
else
{
// foo
}
[bar tend];
}
becomes:
}
}
else
{
// foo
}
[bar tend];
}
I scourged the docs but couldn't find the right setting, maybe it has an unusual name.
Found it. The following will take care of spurious blank lines.
eat_blanks_after_open_brace = TRUE
eat_blanks_before_close_brace = TRUE
nl_max = 2

Comment Line Dissapears After Rewriting a Node

I was writing simple refactoring and noticed a strange thing. The comment line before the node I am rewriting disappears after refactoring. Also comments after the node in question are transferred inside the node and break the indentation in the new place. This is very strange and I want to ask if it is a bug in jdt or I did something wrong and oblivious.
For example my code suppose to refactor if-else statements in a way that the shortest branch would appear first.
when I try to refactor this:
// pre
if(a==6) {
a = 5;
return false;
} else {
a++;
}
//post
I get this:
if (!(a==6)) {
a++;
}
//post
else {
a = 5;
return false;
}
The relevant snippet where the refactoring is done:
protected ASTRewrite createRewrite(CompilationUnit cu, SubProgressMonitor pm) {
pm.beginTask("Creating rewrite operation...", 1);
final AST ast = cu.getAST();
final ASTRewrite rewrite = ASTRewrite.create(ast);
cu.accept(new ASTVisitor() {
public boolean visit(IfStatement node) {
if (node.getStartPosition() > selection.getOffset() + selection.getLength() || node.getStartPosition() < selection.getOffset())
return true;
if (node.getElseStatement() == null)
return true;
int thenCount = countNodes(node.getThenStatement());
int elseCount = countNodes(node.getElseStatement());
if(thenCount <= elseCount)
return true;
IfStatement newnode = ast.newIfStatement();
PrefixExpression neg = negateExpression(ast, rewrite, node.getExpression());
newnode.setExpression(neg);
newnode.setThenStatement((org.eclipse.jdt.core.dom.Statement) rewrite.createMoveTarget(node.getElseStatement()));
newnode.setElseStatement((org.eclipse.jdt.core.dom.Statement) rewrite.createMoveTarget(node.getThenStatement()));
rewrite.replace(node, newnode, null);
return true;
}
});
pm.done();
return rewrite;
}
The // pre comment goes away because the parser considers it to be part of the next statement (represented by node), which you replace with newNode. When node goes away, so does the attached comment.
still thinking about why the // post ends up where it does... Try replacing the newNode before setting its then and else statements

how to check title of uibutton

NSString *title=btn.titleLabel.text;
NSLog(#"Title=%#",title);
if(title == #"SelectCategory")
{
//alert
}
else
{
//somecode
}
I want to check title of UIButton. But my code always executing else statement.
What is the error in this code?
Never compare two strings using '==', use isEqualToString
if ([title isEqualToString:#"SelectCategory"]){
//alert
}else{
//somecode
}
Try this line:
If([btn.titleLabel.text isEqualToString:#"Your text"])
{
//do this
}
else
{
//do this
}
NSString *title=[btn currentTitle];
if([title isEqualToString:#"SelectCategory"])
{
NSLog(#"Equal");
}
Use
if ([title isEqualToString:#"SelectCategory"]) {}
instead of == operator.
Use bun.title is Equalto:#"" it will work for you.
Welcome
Never use == to compare strings, with == you're checking if the pointer of a string is the same of another string, and it's not what you want.
Try this
UIButton *YourButton=btn;
if([[YourButton titleForState:UIControlStateNormal] isEqualToString:#"SelectCategory"])
{
// normal
}
else if([[YourButton titleForState:UIControlStateHighlighted] isEqualToString:#"SelectCategory"])
{
//highlighted
}
else if([[YourButton titleForState:UIControlStateSelected] isEqualToString:#"SelectCategory"])
{
//selected
}
else
{
//somecode
}
Two strings or two objects cannot be compared using ==. To compare two objects you should use isEqual.
In this case :
if([stringToBeCompared isEqualToString:#"comparestring"])
{
//statement
}