Question about invalidate in RCTRootContentView - react-native

Why do you write this code, what problem is it to solve, can you tell me, thank you very much
`
- (void)invalidate
{
if (self.userInteractionEnabled) { // this line
self.userInteractionEnabled = NO; // this line
[(RCTRootView *)self.superview contentViewInvalidated]; // and this line
[_bridge enqueueJSCall:#"AppRegistry"
method:#"unmountApplicationComponentAtRootTag"
args:#[ self.reactTag ]
completion:NULL];
}
}
`

Related

Array Mutation whilst being Enumerated

so my issue is happening only when I have two enemies on a team in my game. If it's a one versus one.. I do not get the issue.
Please look at my code and see if you can gather as to why I'm getting this fatal error.
Removes Target from players target array
-(void)removeTarget:(PlayerClass *)target withSender:(PlayerClass *)sender {
if ([sender.targets containsObject:target]) {
[sender.targets removeObject:target];
}
}
Adds Target to players target array
-(void)addTarget:(PlayerClass *)target withSender:(PlayerClass *)sender {
//check if target already exists
if ([sender.targets count] > 0) {
for (PlayerClass *players in sender.targets) {
if ([players.name isEqualToString:target.name]) {
//Checked if exists, if target exists in list then move on.
goto outer;
}
}
}
[sender.targets addObject:target];
outer:;
}
In the Update to determine whether they're a target or not
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
for (PlayerClass *player in _players) {
....
if (player.health > 0) { //If player is alive!
....
//Checks if the player has targets, if so & visible - Engage.
if ([player.targets count] > 0) {
for (PlayerClass *enemy in player.targets) {
if (![player.team isEqualToString:enemy.team]) {
if (enemy.health > 0) {
if ([self lineOfSightBetweenPlayers:player andPlayer:enemy]) {
[self attackWithPlayer:player againstPlayer:enemy];
break;
} else {
[player removeTarget:enemy withSender:player];
}
} else {
[player removeTarget:enemy withSender:player];
}
} else {
[player removeTarget:enemy withSender:player];
}
}
}
}
Now from debugging I've gathered that the players don't add their team mates as targets. However, the player will gather more than one target if they can see more than one target on the opposing team. However, the issue I'm guessing lies in my technique to removing a target from the array? Can anyone check over and make sure I'm not delivering a school boy error here?
Thanks in advance.
Very simple fix. Wasn't thinking outside the box.. which tends to happen when code starts getting very large!
//Checks if the player has targets, if so & visible - Engage.
if ([player.targets count] > 0) {
for (PlayerClass *enemy in player.targets) {
if (![player.team isEqualToString:enemy.team]) {
if (enemy.health > 0) {
if ([self lineOfSightBetweenPlayers:player andPlayer:enemy]) {
[self attackWithPlayer:player againstPlayer:enemy];
break;
} else {
[player removeTarget:enemy withSender:player];
break;
}
} else {
[player removeTarget:enemy withSender:player];
break;
}
} else {
[player removeTarget:enemy withSender:player];
break;
}
}
}
Fixed my issue, I wasn't breaking out. Thus enumerating after removal.

Wait method run until CCActionSequence finishes

-(void) gameplay
{
if (actionhappen){
CCActionSequence *mySeq = [CCActionSequence actionWithArray:#[do,some,action]];
[mySprite runAction:mySeq]; // it takes 3 seconds.
}
[self checkWinner];
}
-(void)checkWinner{
if (someoneWin){
// I want to wait here until mySeq action finished
[self showWinnerMessage];
}
}
in this code
[self showWinnerMessage] runs before mySeq finished.
How can I wait until the mySprite action finished?
Sleep() seems to make everything sleep.
Well, #LearnCocos2D already answered this question in comments, but here is the code to do this:
-(void) gameplay
{
if (actionhappen)
{
CCActionCallFunc *checkWinner =
[CCActionCallFunc actionWithTarget:self selector:#selector(checkWinner)];
CCActionSequence *mySeq =
[CCActionSequence actionWithArray:#[do,some,action, checkWinner]]; //note checkWinner
[mySprite runAction:mySeq]; // it takes 3 seconds.
}
else
{
// in this case call the func directly
[self checkWinner];
}
}
-(void)checkWinner
{
if (someoneWin)
{
// I want to wait here until mySeq action finished
[self showWinnerMessage];
}
}

How to pass 2 parameters with a self method Cocos2d

This is probably a noobish question that has been answered before, but I can't seem to find a solution online (Google is not being friendly). My question is, relating to Cocos2d, how would I pass 2 parameters using a self method.
An Example of my Code
-(void)Random {
[self AiCharacter:theEvilOne];
[self AiCharacter:theEvilTwo];
}
-(void)AiCharacter(CCSprite*)EvilCharacter {
//stuff
}
But I want to do something like the following
-(void)Random {
num = 1
[self AiCharacter:theEvilOne, Num];
num = 2
[self AiCharacter:theEvilTwo, Num];
}
-(void)AiCharacter:(CCSprite*)EvilCharacter (NSInteger*)num { //This line is what seems to be incorrectly formatted/syntactically incorrect.
//stuff
}
To give you some more info into what I am doing is that I have an multi-dimensional array of values relating to my separate AI Characters and have the num value to differentiate the rows pertaining to each sprite.
The ":" defines a parameter in a method signature. This is how to write it :
-(void)AiCharacter:(CCSprite*)EvilCharacter num:(NSInteger*)num {
}
You can check this post for more information How do I pass multiple parameters in Objective-C?
Try this
-(void)Random {
num = 1
[self AiCharacter:theEvilOne: Num];
num = 2
[self AiCharacter:theEvilTwo: Num];
}
-(void)AiCharacter:(CCSprite*)EvilCharacter : (NSInteger*)num {
//This line is what seems to be incorrectly formatted/syntactically incorrect.
//stuff
}
See the method calling way carefully especially the colons and the parameters... or else you will encounter a crash
-(void)Random {
num = 1
[self AiCharacter:theEvilOne number:num];
num = 2
[self AiCharacter:theEvilTwo number:num];
}
-(void)AiCharacter:(CCSprite*)EvilCharacter number:(NSInteger)num {
}
Try this
-(void)Random {
CGPoint point=ccp(1.0,2.0);
[self AiCharacter:theEvilOne: point];
}
-(void)AiCharacter:(CCSprite*)EvilCharacter :(CGPoint)point {
float x=point.x;
float y=point.y;
}

ios break nested loop

If I have a while loop with a for loop inside of the while loop, how can I break both loops?
I'm doing this because the extra 250ms I get from not completing these loops after I found what I want adds up to be valuable after a while.
pseudocode:
while(alwaysTrue) {
for(NSArray *arr in twoThousandItems) {
if(IFoundWhatIWasLookingFor) {
// assign some stuff here
// break everything, not just the for loop.
}
}
}
This is where goto is your friend. Yes, that goto.
while(alwaysTrue) {
for(NSArray *arr in twoThousandItems) {
if(IFoundWhatIWasLookingFor) {
// assign some stuff here
// break everything, not just the for loop.
goto BAIL;
}
}
}
BAIL:
NSLog(#"Freedom!");
The other option is to have short circuits in your loops.
while(alwaysTrue && !found) {
for(NSArray *arr in twoThousandItems) {
if(IFoundWhatIWasLookingFor) {
// assign some stuff here
// break everything, not just the for loop.
found = YES;
break;
}
}
}
This is one way. This is an applicable technique for other C variants, and other languages as well.
bool breakOuterLoop = false;
while(!breakOuterLoop)
{
for(NSArray *arr in twoThousandItems)
{
if(IFoundWhatIWasLookingFor)
{
// assign some stuff here
breakOuterLoop = true;
break;
}
}
}

Problem with recursive objective-c void-method

thats my first question here and i hope someone can help me.
I´m new at the iPhone programming and want to try an easy app...
It´s an SudokuSolver which is working with an recursive Method. In JAVA this code is making no problems, but in Objective-C the code isn´t stopping when Sudoku is solved. It´s still trying to solve the Sudoku and stops later.
Anyone an idea?!
Here´s the code.
- (SudokuSolver *) initWithField: (int[9][9]) field {
self = [super init];
if(self) {
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
sudokuField[i][j] = field[i][j];
if (field[i][j]) {
sudokuFieldStatic[i][j] = 1;
} else {
sudokuFieldStatic[i][j] = 0;
}
}
}
}
return self;
}
- (void) solve {
[self solveFieldAtRow:0 andCol:0];
}
- (void) solveFieldAtRow: (int) row andCol: (int) col {
if (row > 8) {
return;
} else {
while (sudokuField[row][col] != 0) {
if (++col > 8) {
col = 0;
row++;
if (row > 8) {
return;
}
}
}
for (int num=1; num<10; num++) {
if ([self checkRow:row forNumber:num] && [self checkCol:col forNumber:num] && [self checkFieldAtRow:row andCol:col forNumber:num]) {
sudokuField[row][col] = num;
[self showFieldInConsole:0];
if (col < 8) {
[self solveFieldAtRow:row andCol:col+1];
} else {
[self solveFieldAtRow:row+1 andCol:0];
}
}
}
sudokuField[row][col] = 0;
}
}
The code isn't stopping when the puzzle is solved because you don't check whether the puzzle is solved after the recursive call. So even if the recursive call found a solution, the code just continues on even after finding a solution until it has tried every possibility.
Since you say you have Java code that works, I suggest you compare the logic of the Java program versus this code. You'll probably find the Java code does include such a test.
Edit From your comment above, I see that you won't find such a test in your Java code, because there you are abusing exceptions to "return" from the recursion when a solution is found. The proper way is to have each recursive call return a true value if it found a solution and false if it didn't. And then each step should check if its child call succeeded, and itself return success if so. Something like this:
- (BOOL) solveFieldAtRow: (int) row andCol: (int) col {
if (row > 8) {
// reached the end, so it must have succeeded
return YES;
} else {
while (sudokuField[row][col] != 0) {
if (++col > 8) {
col = 0;
row++;
if (row > 8) {
// reached the end, so it must have succeeded
return YES;
}
}
}
for (int num=1; num<10; num++) {
if ([self checkRow:row forNumber:num] && [self checkCol:col forNumber:num] && [self checkFieldAtRow:row andCol:col forNumber:num]) {
sudokuField[row][col] = num;
[self showFieldInConsole:0];
BOOL result;
if (col < 8) {
result = [self solveFieldAtRow:row andCol:col+1];
} else {
result = [self solveFieldAtRow:row+1 andCol:0];
}
if (result) {
// Our child call succeeded, so we pass that back up
// the stack.
return YES;
}
}
}
sudokuField[row][col] = 0;
// If we get here, we could not find a solution. Return failure
// back up the stack.
return NO;
}
}