How to understand BOOL * - ios

Like in this NSArray instance method enumerateObjectsUsingBlock:^(id x, NSUInteger index, BOOL *stop),as I know BOOL is a primitive type,How can we declare it as a pointer type? why it's not BOOL stop here?

You can wrap other non-object types (such as a pointer or a struct) in an NSValue.
Assuming you really mean a BOOL* (pointer):
NSValue *boolValue = [NSValue value:pointerToBool withObjCType:#encode(BOOL*)];
BOOL *b = [boolValue pointerValue];

Because you're defining stop as a pointer to a BOOL, not as a BOOL itself.
It lets you do things like pass-by-reference emulation in C and Obj-C:
void changeMe (BOOL *pointerToBool) {
*pointerToBool = ! (*pointerToBool); // Dereference the address
// to get at variable.
}
:
BOOL myBool = YES;
changeMe (&myBool); // Pass its address.

BOOL * is pointer of BOOL var. If use it (a pointer) in function argument you can change value of this pointer if you want. Use pointer in argument as a void function, but you can return one or more value in argument

It will help you knowing that BOOL is a signed char, so it can be treated as a it. It's declared in objc.h: http://www.opensource.apple.com/source/objc4/objc4-371.1/runtime/objc.h
The declaration:
typedef signed char BOOL;
#define YES (BOOL)1
#define NO (BOOL)0
BOOL* is pretty much the same as char* , and I'm sure you are more used to see the last.

Related

Objective c set value to a property if not null [duplicate]

I have this code
if ([args valueForKey:#"showSetupScreen"]) {
BOOL showSetupScreen = [args valueForKey:#"showSetupScreen"];
NSLog(showSetupScreen ? #"YES" : #"NO");
// meetingConfig.showSetupScreen = showSetupScreen;
}
Where args is NSMutableDictionary.
args value in my dictionary is NO but when I set to BOOL showSetupScreen = [args valueForKey:#"showSetupScreen"]; it changes into YES
Can someone help me in comprehending why this could be happening.
Attached Screenshot for your reference
A NSDictionary (or NSMutableDictionary) cannot directly contain a primitive C type, such as BOOL. Primitive numeric types (including Boolean) in NSDictionary are wrapped in NSNumber objects. See Numbers Are Represented by Instances of the NSNumber Class and Most Collections Are Objects.
Thus, use NSNumber method boolValue to extract the Boolean from the NSNumber, e.g.,
BOOL showSetupScreen = [[args valueForKey:#"showSetupScreen"] boolValue];
Or, more simply:
BOOL showSetupScreen = [args[#"showSetupScreen"] boolValue];
E.g., examples with primitive C types, including BOOL, NSInteger, and double:
NSDictionary *args = #{
#"foo": #NO,
#"bar": #YES,
#"baz": #42,
#"qux": #3.14
};
BOOL foo = [args[#"foo"] boolValue]; // NO/false
BOOL bar = [args[#"bar"] boolValue]; // YES/true
NSInteger baz = [args[#"baz"] integerValue]; // 42
double qux = [args[#"qux"] doubleValue]; // 3.14
For what it's worth, if you expand the values contained within args, that will show you the internal types for those values, and you will see that that the value associated with showSetupScreen (or foo in my example), is not a BOOL, but rather a pointer to a __NSCFBoolean/NSNumber:
[args valueForKey:#"showSetupScreen"] statement returns pointer (address in memory) and it has two options: some address (non zero value) and NULL (zero). For C programming language true is any non zero value (any address in memory in our case). And for this reason you get true in if operator and in showSetupScreen variable. But it only tells you that there is some object in the dictionary for the specified key, but not the value of this key (the value wrapped in this object). To get this value (BOOL in our case), you must call the boolValue.

Incompatible pointer types initializing 'dispatch_source_t' (aka 'NSObject<OS_dispatch_source> *') with an expression of type 'NSString *'

Hi I am learner in Objective-c Having a warning of Incompatible pointer types initializing 'dispatch_source_t' (aka 'NSObject<OS_dispatch_source> *') with an expression of type 'NSString *'
- (void)stopAnimating {
pause = YES;
if (timerArray) {
for (NSInteger i = 0; i < [timerArray count]; i++) {
dispatch_source_t _timer = [[timerArray objectAtIndex:i] source];
dispatch_source_cancel(_timer);
_timer = nil;
}
timerArray = nil;
}
[self removeAllFlakesWithAnimation:YES];
}
in dispatch_source_t _timer = [[timerArray objectAtIndex:i] source]; this line, how to solve, timeArray is a NSMutableArray NSMutableArray *timerArray;
We can't tell you what is wrong with your code, there is not enough information for that, but we can tell you what the compiler is doing and why it produces the error it does – then you'll have to resolve it from there.
In your line:
dispatch_source_t _timer = [[timerArray objectAtIndex:i] source];
The LHS declares are variable, _timer, of type dispatch_source_t so the RHS needs to return a value of this type. Let's look at the RHS:
[timerArray objectAtIndex:i]
which BTW you can write more succinctly as:
timerArray[i]
this indexes into an array which you have declared as:
NSMutableArray *timerArray;
the elements of an array like this have type id – which means a reference to any object. The actual type of the objects in the array in this case will not be known until runtime. The next part of the RHS is:
[<a reference so some object> source]
Objective-C allows this and will perform a check at runtime to determine that the reference object does indeed have a method source. However at compile time the compiler can look up the definition of methods called source, it does, and finds that the method returns an NSString *.
So the RHS returns an NSString * and the LHS requires an dispatch_source_t and therefore the compiler reports:
Incompatible pointer types initializing 'dispatch_source_t' (aka 'NSObject<OS_dispatch_source> *') with an expression of type 'NSString *'
Now you have to figure out whether you intended to call source or some other method which does return a value of the right type, etc. HTH
As another BTW to someone learning Objective-C: You are using a for loop to produce an index value for an array, and you only use that value to index the array once. A better way to do this is to use a for/in loop:
for (<YourObjectType> element in timerArray) {
dispatch_source_cancel([element source]);
}
You need to replace <YourObjectType> with the type of object references you've stored in timerArray, and as above the source method needs to return a dispatch_source_t value.
Objective-C has a for ... but there are other really nice ways in which you can iterate through elements of an array. I give one example for array a, in this case of NSString *
[a enumerateObjectsUsingBlock: ^ ( NSString * i, NSUInteger idx, BOOL * stop ) {
// do something with NSString * i
// its index into the array is idx if you need it
// to exit out of the loop do
* stop = YES;
}];

Pass a variable to decimalNumberHandlerWithRoundingMode?

Forgive me if I use the wrong terminology as I'm still a little new at iOS development. I've built a calculator-type app and I want users to be able to control how numbers are rounded. Here's the code I'm using:
-(NSString*)calculateWidthFromHeightString:(NSString*)height usingDimensions:(Favorite*)dimensions{
int decimalPlaces = [self.userData.rounding intValue];
NSUInteger *roundingMethod;
if ([self.userData.roundingMode isEqualToString:#"up"]) {
roundingMethod = NSRoundUp;
}
else if ([self.userData.roundingMode isEqualToString:#"plain"]) {
roundingMethod = NSRoundPlain;
}
else {
roundingMethod = NSRoundDown;
}
NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMethod
scale:decimalPlaces
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
This works as expected, but I'm getting the following compiler warning where I assign the rounding mode to the pointer "roundingMethod":
Incompatible Integer to pointer conversion assigning to ‘NSUInteger *’
(aka ‘unassigned long *) from ‘NSUInteger’ (aka ‘unassigned long’)
Incompatible Integer to pointer conversion assigning to ‘NSUInteger *’
(aka ‘unassigned int *) from ‘NSUInteger’ (aka ‘unassigned int’)
I don't really know what this means. Any help would be greatly appreciated.
This line:
NSUInteger *roundingMethod;
should be:
NSUInteger roundingMethod;
NSUInteger is a native type, not a class type.

Incompatible inter to pointer conversion

The following code generates compiler warning (below the code)
NSUInteger positionat = [_bhkButtons indexOfObject:sender];
BOOL val = (BOOL) [_searchModel.BHkNo objectAtIndex:positionat];
val = !val;
[_searchModel.BHkNo insertObject:val atIndex:positionat];
Incompatible integer to pointer conversion 'BOOL' (aka 'signed char') to parameter of type 'id'
I'm a newbie to Objective - C. Please help.
Since BOOL is a primitive data type and arrays take in objects, you have to box/wrap the BOOL variable. You can use the NSNumber class for the same as shown below.
[_searchModel.BHkNo insertObject:[NSNumber numberWithBool:val] atIndex:positionat];

Incompatible integer to pointer conversion assigning to 'int *' from 'int'

I have yet another pesky warning I would like gone. Basically, I have an int declared like this: #property (nonatomic, assign) int *myInt; and set like this: myInt = 0;. It is also synthesized in the implementation file. I am getting a warning on the line where I set the int's value and it says Incompatible intiger to pointer conversion assigning to 'int *' from 'int'. What should I do to fix this?
There's a big hint in the error message!
In C and Objective C, an int is a primitive data type. You've written int *, which means "a pointer to an int", whereas it looks like you just wanted an int.
So change your property to this:
#property (nonatomic, assign) int myInt;
For more info, google "C pointers" and you'll find information like this: http://pw1.netcom.com/~tjensen/ptr/pointers.htm
Yes, simply remove asterisk (*) from declaration.
for example.declare BOOL isChecked instead of BOOL * isChecked.
int *MyInt is a pointer to int, not an int.
As others told you, just remove the * and you will have a regular int.
Another way to resolve this is to simply not declare a pointer (drop the asterisk):
#interface ViewController : UIViewController {
NSUInteger myObjcInt; // unsigned ( >= 0 ) NSObject int, yo
}

Resources