iOS can't alloc new object in switch case [duplicate] - ios

This question already has answers here:
Compile Error with: switch, "expected expression before"
(3 answers)
Closed 8 years ago.
I have a switch case like this:
switch ([weatherCode intValue]) {
case 1:
...
break;
case 2:
....
break;
}
But i want to alloc an object in that case, like NSString *string = #"hello";
but it keep gives me an error expect expression which i don't understand what's going on at all. Please help.
Thanks.

I had same problem before, simply add a {} in your case, all your problem will be solved.
Such as:
switch ([weatherCode intValue]) {
case 1:
{
...
}
break;
case 2:
{
...
}
break;
}

You need braces if you want initialise variable:
switch ([weatherCode intValue]) {
case 1:{
NSString *string = #"hello";
}
break;
case 2: {
....
}
break;
}

In (Objective-)C(++) the statements while(...) { ... }, for(...) { ... }, switch(...) { ...} etc. contain a single block statement (if (...) { ... } else { ... } contains two). The scope of declarations within a block is just that block, and it is an error to declare the same variable twice within a block.
The block of a switch contains a number of case ...: labels - labels do not delimit blocks, they are just points within a block that control flow can jump to. This makes switch statements in C different than in some other languages where each branch is independent (as the two blocks in an if/else are independent in C). A C switch is just a "computed goto" into a single block. This is why the break; statement exists, without it control flow just continues from one "branch" to the next.
Another consequence of this is that different branches cannot declare the same variable names, unlike for if/else statements.
Finally only statements and not declarations can be labelled, and as a case ...: is a form of label there cannot be a declaration immediately following one - so you cannot start a "branch" with a declaration.
If the variables you wish to declare within a branch are for use only in that branch (as they would be if declared in either of the blocks of an if/else) then you can solve all the problems by enclosing the branch in braces, { ... }, to make it into a block statement - blocks can be labelled and can contain local declarations. E.g. something along the lines of:
switch (expr)
{
case 1:
{
NSString *var;
// use var
break;
}
case 2:
{
NSNumber *var;
// use var
break;
}
...
}
// no var here
If you are assigning to variables which you need to use after the switch then you must declare them before the switch, as the body of a switch is a block and hence a local declaration scope. E.g. something along the lines of:
NSString *var = nil;
switch (expr)
{
case 1:
...
var = ...;
break;
case 2:
...
var = ...;
break;
...
}
// use var here
HTH

Try doing it like this:
switch ([weatherCode intValue]) {
case 1: {
...
}
break;
case 2: {
....
}
break;
...
}

Use some braces :
switch ([weatherCode intValue]) {
case 1:{
NSString *string = #"hello";
}
break;
case 2:{
NSString *string = #"hello";
}
break;
}

In the switch, cases acts like block so you may need to set the { }. You don't need to explicitly alloc the NSString if using ARC.
switch ([weatherCode intValue]) {
case 1:
{
//your code for case 1
}
break;
case 2:
{
//your code for case 2
}
break;
}

Related

IOS expected expression error

I want to use an if-statement inside the switch but I keep getting an expected expression error. I would be grateful if anyone could help me to solve this issue.
switch ([ApplicationModel getApplicationType]) {
case CSApplication: {}
break;
case RAApplication:
{
if (indexPath.row == FloorLevelIndex || indexPath.row == RoomIndex)
{
[cell setUserInteractionEnabled: YES];
}
}
break;
default:
break;
}
If FloorLevelIndex and RoomIndex are types, you won't be able to compare a number to a type (hence the error). You probably want the number representation of those or define them with a NSInteger value
Make sure that [ApplicationModel getApplicationType] returns the valid data type that swtich case supports.
The variable used in a switch statement can only be integers,
convertable integers (byte, short, char), strings and enums
Should be like this:
switch ([ApplicationModel getApplicationType]) {
case CSApplication:
break;
case RAApplication:
if (indexPath.row == FloorLevelIndex || indexPath.row == RoomIndex)
{
[cell setUserInteractionEnabled: YES];
}
break;
default:
break;
}
I just tried this code in my Xcode and it works fine:
NSLayoutAttribute attr = NSLayoutAttributeLeft;
switch (attr) {
case NSLayoutAttributeTop: {}
break;
case NSLayoutAttributeLeft: {
if (YES) {
NSLog(#"works");
}
}
break;
default:
break;
}
So the structure of your switch statement is correct.

complementery of an if case

How would you write this:
if case .SomeEnum(3) = enumType where myInt == 3 {
//I don't need this case
} else {
//This is the case I need
}
I know I could use guard:
guard case .SomeEnum(3) = enumType where myInt == 3 else {
//This is the case I need
}
but I don't think it is clean, since it is not really a case in which the function is not able to finish. Also, guard expects me to return from the function.
Any other alternatives?
You cannot negate a pattern (as far as I know), and your first solution
using if/else looks fine to me, the intention of the code is clearly
visible.
A switch statement would be an alternative:
switch enumType {
case .SomeEnum(3) where myInt == 3:
break // I don't need this case
default:
// This is the case I need
// ...
}
With regard to your remark
Also, guard expects me to return from the function.
that is not entirely true. You are expected to leave the current scope.
So this would compile and work as expected:
repeat {
guard case .SomeEnum(3) = enumType where myInt == 3 else {
// This is the case I need
// ...
break
}
} while false
but I would not consider that a better solution.

breaking out of a switch within a foreach loop closure

I have the following code
void onSelectionChangedFiredSources( Event event, var detail,
SelectCheckboxMenuComponent target)
{
// getItemModels returns a list of objects
getItemModels( target.selectedItems )
..forEach( (item)
{
switch( item.label )
{
case 'Ear':
toggleDialog( 'paper-dialog-transition-center',
$['ear-side-dialog']);
break;
case 'Eye':
toggleDialog( 'paper-dialog-transition-center',
$['eye-side-dialog']);
break;
case 'Nostril':
toggleDialog( 'paper-dialog-transition-center',
$['nostril-side-dialog']);
break;
case 'Thorax':
toggleDialog( 'paper-dialog-transition-center',
$['thorax-side-dialog']);
break;
default:
srcDataMap.add( item.label, item.selected);
}
});
}
When a case is triggered, I would like to break out of the foreach loop.
Note that each time the selection changes, all selections are return by the target.selectedItems expression. So if 'Ear' is the first selection, the loop is executed and when 'Eye' is then selected the list return will have both Ear and Eye.
How is this best done?
Thanks
You can't break a forEach call.
You can't use break because it's not a loop. It's a function call, and break only works inside the current function.
You can't return, because that just continues with the next element.
You can throw to end the forEach, but that's hardly pretty.
What you can do instead is to not use forEach at all, and use a for-in loop instead, and then break out of that using a labeled break:
void onSelectionChangedFiredSources(Event event, var detail,
SelectCheckboxMenuComponent target) {
// getItemModels returns a list of objects
var models = getItemModels(target.selectedItems);
loop: for (var item in models) {
switch (item.label) {
case 'Ear':
case 'Eye':
case 'Nostril':
case 'Thorax':
toggleDialog('paper-dialog-transition-center',
$['${item.label.toLowerCase()}-side-dialog']);
break loop;
default:
srcDataMap.add( item.label, item.selected);
}
}
}
You need to use a labeled break because without a label it would only be breaking the switch statement.

IOS Photon Cloud SDK getRoomList function doesn't work

I am developing cocos2d-x game which have online game mode.
Online game designed and implemented by Photon Cloud SDK(http://www.exitgames.com).
I implemented only ios version but it doesn't work.
The codes that I have implemented are blow.
void NetworkLogic::opJoinRandomRoom()
{
ExitGames::Common::JVector<ExitGames::LoadBalancing::Room> roomList;
roomList = mLoadBalancingClient.getRoomList();
int count = roomList.getSize();
CCLog("Room Count = %d", count);
if(count == 0)
{
this->opCreateRoom();
}else{
mLoadBalancingClient.opJoinRandomRoom();
}
}
void NetworkLogic::update(float dt)
{
this->run();
}
void NetworkLogic::run(void)
{
if(mLastInput == INPUT_EXIT && mStateAccessor.getState() != STATE_DISCONNECTING && mStateAccessor.getState() != STATE_DISCONNECTED)
{
disconnect();
mStateAccessor.setState(STATE_DISCONNECTING);
}
else
{
State state = mStateAccessor.getState();
switch(state)
{
case STATE_INITIALIZED:
connect();
mStateAccessor.setState(STATE_CONNECTING);
break;
case STATE_CONNECTING:
break; // wait for callback
case STATE_CONNECTED:
{
ExitGames::Common::JVector<ExitGames::LoadBalancing::Room> roomList;
roomList = mLoadBalancingClient.getRoomList();
int count = roomList.getSize();
ExitGames::Common::JString tmp;
tmp = count;
EGLOG(ExitGames::Common::DebugLevel::INFO, tmp);
CCLog("Room count in Room = %d", count);
switch(mLastInput)
{
case INPUT_CREATE_GAME: // create Game
opCreateRoom();
break;
case INPUT_JOIN_RANDOM_GAME: // join Game
opJoinRandomRoom();
mStateAccessor.setState(STATE_JOINING);
break;
default: // no or illegal input -> stay waiting for legal input
break;
}
break;
}
case STATE_JOINING:
break; // wait for callback
case STATE_JOINED:
switch(mLastInput)
{
case INPUT_LEAVE_GAME: // leave Game
mLoadBalancingClient.opLeaveRoom();
mStateAccessor.setState(STATE_LEAVING);
break;
default: // no or illegal input -> stay waiting for legal input
break;
}
break;
case STATE_LEAVING:
break; // wait for callback
case STATE_LEFT:
mStateAccessor.setState(STATE_CONNECTED);
break;
case STATE_DISCONNECTING:
break; // wait for callback
default:
break;
}
}
mLastInput = INPUT_NON;
mLoadBalancingClient.service();
}
First I run one app then getRoomList function returns 0 values.
Also after first room created and run second app but it also returns getRoomList function 0.
Please help me.
I have just taken the code that you have provided in your question and copied it into the according place inside the demo of an otherwise unchanged version 3.2.2.0 build of the Photon C++ Client SDK (and removed the two CCLog() lines to make it compile without cocos2d-x) and it worked just fine for me:
The demo prints 0 for the size of the room list until I let one client create a room. Afterwards the other client prints 1.

How to capture state - More flexible than BOOL but more distinct than NSString

I am calling a method to set a state, in this case animateState. The state parameter can be one of a defined set: e.g. "hide", "show", "active", "inactive". So it's more than BOOL but more distinct than an open NSString.
Currently I am solving this by using a NSString and check the state using its isEqual method. It's working but not ideal.
-(void) animateState:(NSString*)state{
if ([state isEqual:#"hide"]){
...
} else if ([state isEqual:#"show"]){
...
} else if ([state isEqual:#"active"]){
...
} else if ([state isEqual:#"inactive"]){
...
}
}
How can I restrict the parameters and eventually make the if/switch checks more efficient? Any best-practice for such a case?
An enum wil do nicely here, define the enum somewhere in a header file:
typedef enum{
AnimateStateHide,
AnimateStateShow,
AnimateStateActive,
AnimateStateInactive
} AnimateState;
Then you can call your methode like:
-(void) animateState:(AnimateState)state{
switch(state) {
case AnimateStateHide:
//Code here;
break;
case AnimateStateShow:
//Code here;
break;
case AnimateStateActive:
//Code here;
break;
case AnimateStateInactive:
//Code here;
break;
}
}

Resources