I have defined a macro like this,
#define SELECTED_SITE_ID (SITE_MANAGER.selectedSite.siteCollectionIdentifier)
It's returning a double value which was stored in user defaults.
In code, SELECTED_SITE_ID macro is using for more than 1000 places like this,
int a = SELECTED_SITE_ID;
NSArray *array = [someClassObject objectAtIndex:a-1];
As my app is running for the first time, SELECTED_SITE_ID macro is returning 0.0, that's assigned to int a; so a will be 0.
Where from array, I have written a-1 to 0-1, this leads to a crash issue.
I don't know what's the quick way to fix this for now, as it's written at approx. 1000 places?
What I think?
I guess inside macro itself? If I would able to check, what's the value coming? if it's 0 then I will explicitly return 1.
Any help would be appreciated.
That was easy,
#define SELECTED_SITE_ID ((SITE_MANAGER.selectedSite.siteCollectionIdentifier <= 0.0) ? 1 : SITE_MANAGER.selectedSite.siteCollectionIdentifier)
Better way is:
#define SELECTED_SITE_ID (SITE_MANAGER.selectedSite.siteCollectionIdentifier? :1)
Related
I don't know how to find keyword for this (*-) in Google, and I don't know what is name. So I ask here.
Sample code :
StartDate:=IncMinute(FinishDate,TotalMinutes*-1);
What is TotalMinutes*-1 if I write in 'normal' syntax ?
It is multiplying TotalMinutes by -1... IOW, it looks like it is decrementing the Minutes.
Write it like this: TotalMinute * -1 and it is more clear. The * is the multiplication operator and the - is the unary minus operator.
I know #define must be constant but please give me any good tips.
In my case, I define a constant value by #define (e.g. #define kImageQuality 0.7).
However, I would like to change the constant value from Settings.Bundle before opening an app.
That means to change the constant value, doesn't it?
Is that any way to implement as my aim?
It should change to instance variable instead of #define?
Any tips given by you that would be really appreciated.
#define constants are replaced before compilation even begins by the preprocessor (e.g. kImageQuality gets replaced by 0.7 before compilation). Therefore loading it before the app starts is impossible as the app does not recompile every time. You need to use a variable:
float imageQuality = 0.7f;
This is not possible because this:
#define constant 3
...
y = x + constant
Is completely equivalent to this:
y = x + 3
#defined constants are replaced by their value in the preprocessing stage before the code is even compiled. To change the value dynamically, you have to either use a global variable, or some other persistent mechanism like NSUserDefaults.
In my program I am holding the pixel data of a UIImage in a basic C array:
// It can be UInt8 as it is greyscaled, values can only be 0-255
#property (nonatomic, readwrite) UInt8 *imageData;
Now in my greyscaling algorithm I initialize it:
self.imageData = malloc(sizeof(UInt8) * width * height);
then I fill in the data as I greyscale. This works. However, in a later algorithm I go through and make values either 0 or 255 through some magic. I thought that was working fine... but a later algorithm looking for these values was getting 1's and 3's. So I went and threw this in right after I change the value from 0-255 to be either 0 or 255:
// Magic loop. Starts with current value at pixelIndex, gets curVal.
self.imageData[pixelIndex] = curVal;
NSAssert(self.imageData[pixelIndex] != curVal, #"Whattt");
And lo and behold it isn't actually changing the value of my array. Is there something I'm missing? Are these arrays a one time set and then they become readonly? I know NSArrays are like that, but this is just a simple C pointer-based array... or are they the same?
Whatever the reason, how can I make it so I can properly alter these values?
This should work fine. I think your problem is just that you have your assertion backwards — the condition is supposed to be an expression that you want to be true, so currently you are asserting "After I set self.imageData[pixelIndex] to be curVal, it should not be equal to curVal." Instead, that should be:
NSAssert(self.imageData[pixelIndex] == curVal, #"Whattt");
BTW, when doing this sort of assertion, I always think it's helpful to include the expected and actual values so you can see what's going on. In this case, you could do:
NSAssert3(self.imageData[pixelIndex] == curVal, #"Image data at pixel index %d should have been %d, but instead was %d", pixelIndex, curVal, self.imageData[pixelIndex]);
This would make it more obvious that the values actually are equal and something is going wrong in your equality check.
I am having a hard time finding the number of rows clicked. What I found was
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
But I got a crazy number from that. I have an UITableView that shows an array with 4 items.
I also tried this:
NSIndexPath *leo = [self.tableView indexPathForSelectedRow];
NSInteger *leo2 = leo.row;
But leo2 is always 0. What can I do?
You have the two parts, you just need to put them together. Is this what you're looking for?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger leo2 = indexPath.row;
id someObject = myArray[leo2];
}
As #nkongara points out, you had added an asterisk next to the name of the pointer implying that it was an Objective C object, when infact it is a primitive type. In this case either long or int depending on the system. For more information, see how NSInteger and NSUInteger are defined below.
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
Your code, as written should have given you a compiler warning.
A good rule of thumb: Find an fix every single compiler warning, no exceptions. They always indicate that's there is something wrong. Sometimes that something causes wrong results rather than crashes, but there is always a reason for compiler warnings.
One of the worst thing about warnings is that they are only displayed when you edit a source file. If you ignore them, the compiler treats the file as compiled successfully, and so you don't see the warning again unless you edit the file, or if you run a "clean" on your project. This means that if you don't fix a warning, it becomes invisible. Bad. Very bad.
Sometimes the fix is a type cast so the compiler knows the type of an object. Other times, like above, the answer is to get rid of a spurious asterisk.
Another example of code that should be changed to get rid of a warning:
We've all written the if statement
if (a == b)
(which means "if a equals b")
as
if (a = b)
instead, by accident. This second statement is technically legal, but almost always wrong. What it means is: Copy the right side of the = statement into the left side (set a to the value of b.) Then evaluate the result of the right side as the result of the if statement. So the if statement will be true if b is not equal to zero.
The LLVM compiler flags if (a = b) with a warning because this is such a common mistake. If you really, really want to do that, you can add an extra set of parenthesis:
if ((a = 0))
That tells the compiler that you really mean to do this. (I say anyone doing that should be shot, but that's a different issue...)
This is an example of modifying your code to make your intentions clear, both to the compiler, and to other people reading your code.
I get the warning Comparison of unsigned expression >=0 is always true
In this line:return status != nil && status.length >= 0 && status.length <= 140;
So I am not sure if this sounds stupid or not but should I just delete that expression then>
Thanks!
Remove just this part of a check — status.length >= 0. Actually this part of a check will be optimized by compiler and removed automatically as it not make sense. Removing it form a code will help you to get rid from this warning.
Yes - since length returns an unsigned integer, it will always be 'greater than or equal to 0'. You can delete the status.length >= 0 portion of the conditional.
If you want to make sure that you don't have a zero-length string, then you should use the condition status.length > 0.
Otherwise, you can remove that condition, as others have mentioned.
You must have written a statement which can never be executed
I am having this because i do something like this..
if (textField.text.length < 0) //wrong logic
textField's text length can never be less than 0 . It must be at least 0.
Whenever complier see such kind of logical error which can never be possible (executed) . It generates this kind of Warning. If anyone is having this error so properly check your logic .