Objective C, declard nsstring by "if statement" [duplicate] - objective-c

This question already has answers here:
Objective C - XCode not recognizing variable outside of if statement
(2 answers)
Closed 8 years ago.
New in OBJ-c,
Im tring to set a varible with some if statement and it's not work.
if (_imageView,image==NULL) {
NSString *isFileSet = #"NOFILE";
}
else
{
NSString *isFileSet = #"FILESET";
}
NSLog(#"%#",isFileSet);
and I cant run the project, I get an err: "Use of undeclared identifier "isFileSet".
what is worng here ?

That's because you declared the variables in the if block. The variable won't exist outside of it (true for all programming languages I can think of). You should have declared it outside:
NSString *isFileSet;
if (_imageView.image==NULL) {
isFileSet = #"NOFILE";
}
else
{
isFileSet = #"FILESET";
}
NSLog(#"%#",isFileSet);
You should have also fixed the if-statement.

Related

How to create a 2darray in kotlin of objects? [duplicate]

This question already has answers here:
2D Array in Kotlin
(11 answers)
Closed 1 year ago.
I am genuinely shocked on how hard it is to find a good explanation on how to create a 2d array in Kotlin for an object.
These are my attempts from what I have found neither here on stack and online neither work, why? how do I create a 2d array of objects not built into Kotlin!!!
var matrix : Array<Array<myObject?>> = null
//var arr2D = Array(10) { Array(10) { myObject(this) } }
for (i in 0 until 9) {
for (j in 0 until 9) {
matrix[i][j] = myObject(this)
}
}
It says "null can not be a value of a non-null type" so I guess I have to use an arrayofnulls(), but cannot find a source can someone help me or give me a source?
This is how you create a 2D Array in Kotlin with a user made object. ArrayofNulls allows you to set all indexes in the array to null and then just initialize them later with a for loop!
val matrix = Array(10) {
arrayOfNulls<myObject?>(
10
)
}

Operator call corresponds to a dot-qualified call which is not allowed on a nullable receiver error [duplicate]

This question already has answers here:
Kotlin Map with non null values
(5 answers)
Closed 4 years ago.
This code doesn't compile:
val map = mutableMapOf<Int, Int>()
ar.forEach{
if(!map.containsKey(it)) {
map[it] = 1
} else {
map[it] = map[it] + 1
}
}
This is the compilation error:
Operator call corresponds to a dot-qualified call 'map[it].plus(1)'
which is not allowed on a nullable receiver 'map[it]'.
Since the mutableMap I created is not having nullable parameters, I am wondering why do I need to add not null checks later on? This code passes:
else map[it] = map[it]!! + 1
It's because map[it] might return null if there's no entry in the map corresponding to that key. Even though you checked by calling containsKey on the line before, that doesn't guarantee that when you call map[it] you'll get a value back, as another thread might update the map's contents in between those two calls.

Differences in for-loops. Swift v.s. Objective-C [duplicate]

This question already has answers here:
Removing from array during enumeration in Swift?
(9 answers)
Closed 6 years ago.
In this loop we have the potential to reduce the number of items in the loop while processing it. This code works fine in Obj-C, but the Swift loops don't get the message that an item has been removed and end up overflowing the array.
In Objective-C, we had:
for(int i = 4; i < staticBlocks.count; i++)
{
PlayerSprite* spr = [staticBlocks objectAtIndex:i];
[spr setPosition:CGPointMake(spr.position.x, spr.position.y-1)];
if(spr.position.y < -1000)
{
[staticBlocks removeObject:spr];
[spr removeFromParent];
}
if(spr.blockTypeIndex == Block_Type_Power_Up)
{
[spr update];
}
}
In Swift I know of these options:
//for i in 4.stride(to: staticBlocks.count, by: 1){ //crashes
//for i in 4..<staticBlocks.count{ //crashes
for var i = 4; i < staticBlocks.count; i += 1 { //works, but is deprecated
let spr = staticBlocks.objectAtIndex(i) as! PlayerSprite
spr.position = CGPointMake(spr.position.x, spr.position.y-1)
if(spr.position.y < -1000)
{
staticBlocks.removeObject(spr)
spr.removeFromParent()
//break
}
if(spr.blockTypeIndex == k.BlockType.PowerUp)
{
spr.update()
}
}
In this specific case, it really isn't a problem for me to use a break statement (which is currently commented out) to kill the loop and prevent the crash, but it doesn't seem like the proper fix. I assume there will come a time when I need to know how do do this correctly. Is there a non deprecated way to do a for loop, one which processes the count each pass?
A related, unanswered question.
Is the for loop condition evalutaed each loop in swift?
I don't know how to link to a specific answer, but this code did what I needed. Marking as duplicate now.
Removing from array during enumeration in Swift?
var a = [1,2,3,4,5,6]
for (i,num) in a.enumerate().reverse() {
a.removeAtIndex(i)
}
This is because in Swift you cannot remove items from an array while you are iterating over it.
From this question Removing from array during enumeration in Swift?
you can see that you should be using the filter function instead of using a for loop.
For example, don't do this:
for (index, aString: String) in enumerate(array) {
//Some of the strings...
array.removeAtIndex(index)
}
Do something like this:
var theStrings = ["foo", "bar", "zxy"]
// Filter only strings that begins with "b"
theStrings = theStrings.filter { $0.hasPrefix("b") }
(Code example from this answer)
Additionally, it should be noted that filter won't update the array, it will return a new one. You can set your array to be equal to that array afterwards.
An additional way to solve the issue, from the same question is to do this:
var a = [1,2,3,4,5,6]
for (i,num) in a.enumerate().reverse() {
a.removeAtIndex(i)
}
print(a)

Working with recursive anonymous blocks in Objective-C [duplicate]

This question already has answers here:
Objective-C Blocks, Recursion Fails
(3 answers)
Closed 9 years ago.
I love JavaScript's ability to define functions as variables and am trying to do something similar in Objective-C. In particular, I want to write a recursive function using an anonymous block that I can call on an object and have it work its way through a tree, applying a change at each node:
void ( ^setDetailsLoaded )( Product* ) = ^void ( Product* prod ) {
prod.detailsLoaded = true;
for ( Group* group in prod.groups ) {
for ( Product* mod in group.mods )
setDetailsLoaded( mod );
}
};
setDetailsLoaded( product ); <-- error here
However, I'm getting the strange error error: address doesn't contain a section that points to a section in a object file[sic] when I run the program (which compiles fine).
I'm just wondering if perhaps I need to retain the block or something, or if I should just do this with function pointers instead of blocks.
Because of the way blocks are implemented—they make a const copy of all primitive type variables, and a strong reference to all object type variables referenced in them at creation time—attempting to recursively reference a block within itself will result in the crash that you saw.
You can solve this by using the __block annotation on the block variable itself:
__block void ( ^setDetailsLoaded )( Product* ) = ^void ( Product* prod ) {
prod.detailsLoaded = true;
for ( Group* group in prod.groups ) {
for ( Product* mod in group.mods )
setDetailsLoaded( mod );
}
};
See #bbum's blog post on blocks for more details (specifically tip #7).

Comparing NSStrings seems not to work [duplicate]

This question already has answers here:
Comparing Strings in Cocoa
(5 answers)
Compare two NSStrings
(3 answers)
Closed 10 years ago.
I am having some very frustrating trouble on what I'm sure is a very simple problem, but I cannot seem to fix it. I have an NSArray called final that outputs as follows:
final = (
".DS_Store",
"hey.txt"
)
I want the following for loop to return false for the first pass and true for the second. As far as I can tell I have it made correctly but the output is true for both passes.
for (int i = 0; i < [final count]; i++) {
if (final[i] != #".DS_Store") {
NSLog(#"true");
}
else {
NSLog(#"false");
}
Outputs:
2013-02-20 17:20:39.042 myAppName [40636:403] true
2013-02-20 17:20:39.042 myAppName [40636:403] true
I cannot figure out why the first one does not return false. Any Ideas?
You are comparing pointers. Use [final[i] isEqualToString:#".DS_Store"] to compare strings.