views:

56

answers:

1

I am trying to set the text of a UILabel to be equal to the name of the day of the week represented in an NSDateComponents. I am using the following code:

NSDateComponents *dateComponents = [[[NSDateComponents alloc] init] autorelease];
dateComponents.weekday = 1; //Sunday
NSString * const weekdayNames[8] = {@"Array starts at 1", @"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday"};

UILabel *myLabel = [[[UILabel alloc] init] autorelease];
myLabel.text = weekdayNames[dateComponents.weekday]; //compiler error: Assignment of read-only variable 'prop.49'

I can make the code work in any of three ways:

  1. Make weekdayNames not be const
  2. Assign dateComponents.weekday to an intermediate int variable before using it as an array index
  3. Assign weekday[dateComponents.weekday] to an intermediate NSString * variable before calling setText:

But I want to know why my code, as originally written, fails.

A: 

You are not initializing NSDateComponents properly, thus weekday does not return the value you expect. See the documentation.

This is now you would initialize it using the current date:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
int weekday = [weekdayComponents weekday];

Later edit: Initialization is part of the problem, to fix the compiler error change:

NSString * const weekdayNames[8] =

to

NSString const * weekdayNames[8] =

(pointer to a constant NSString).

However, when you do that you will hit a warning "passing argument 1 of 'setText:' discards qualifiers from pointer target type" because you're passing a constant pointer to a function that expects a pointer. To fix the warning you can cast the argument to setText to (NSString *).

It probably makes sense to remove the const qualifier altogether. NSStrings are already immutable in Objective-C, so they're already constants.

diciu
That does not seem to be the problem. I tried your way of initializing NSDateComponents, and just as before, setText: only works with an intermediate variable or with non-const weekdayNames. Besides, the very documentation you link to initializes NSDateComponents *comps the same way I originally did, in their very first code example (bottom of page 5 in the PDF).
Jon Rodriguez
You are correct that making the pointer non-const does make the code compile. But, if you know, I still want to understand why it doesn't work with a const pointer. Just reading the Obj-C code, I think that my original example was perfectly legal. Is the compiler somehow modifying the weekdayNames pointer when doing pointer arithmetic, then modifying weekdayNames back to the orginal value? If so, that seems like an illegal optimization on the compiler's part...
Jon Rodriguez
Clang compiles the code fine. When I run gcc with "-fdump-tree-original" it shows that it's trying to assign inside the const weekdayNames. Replacing "myLabel.text" with "[myLabel setText:]" makes the problem go away - it may be a GCC bug.
diciu
Thank you for your newest comment! That comment answers my question so I am now accepting your answer.
Jon Rodriguez