Objective-C – Expected identifier error - objective-c

I'm getting an expected identifier error when I try to compile my code.
careerURL is setup like this in .h file:
#property (nonatomic, copy) NSString *careerURL;
And synthesized like this in .m file:
#synthesize careerURL;
I really do not understand what is the issue here. The exact code works in another viewcontroller.

You should either use dot . syntax,
NSString *wtf = self.careerURL;
Or Objective-C message syntax,
NSString *wtf = [self careerURL];
Not both at the same time.

You should write:
NSString *wtf = self.careerURL;
When you are writing [object method] it is expected that you want to call method method from object object. If you want just access some value (that is defined as #property) you can type:
[self nameOfValue];
or
self.nameOfValue;

Related

How to use #property correctly (Setters) within another class

another question i'm trying to use a setter within another class but I seem to get this odd error here is the code below:
AppDataSorting.h
#import <Foundation/Foundation.h>
#interface AppDataSorting : NSObject{
NSString *createNewFood;
NSNumber *createNewFoodCarbCount;
}
#property (readwrite) NSString *createNewFood;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
- (IBAction)saveData:(id)sender {
NSLog(#"%#", self.foodName.stringValue);
self.createNewFood = self.foodName.stringValue;
NSLog(#"%.1f", self.carbAmount.floatValue);
}
#end
I get the error message in AppDelegate.m which is: Property 'createNewFood' not found on object of type 'AppDelegate *'
Could someone please explain the issue here?
You declare this property:
#property (readwrite) NSString *createNewFood;
In AppDataSorting.h so you can access it like self.createNewFood in AppDataSorting.m file not AppDelegate.m. If you want to call it as you do in AppDelegate.m you have move this line:
#property (readwrite) NSString *createNewFood;
to AppDelegate.h file.
Or if you want to use property from AppDataSorting class in AppDelegate you have to create object and call it on that object:
- (IBAction)saveData:(id)sender {
NSLog(#"%#", self.foodName.stringValue);
AppDataSorting *dSorting = [[AppDataSorting alloc] init];
dSorting.createNewFood = self.foodName.stringValue;
NSLog(#"%.1f", self.carbAmount.floatValue);
}
In -saveData:, self refers to an instance of NSAppDelegate. The createNewFood property is defined on instances of the class AppDataSorting.
Also note that Cocoa/CF naming conventions give special meaning to methods that start with "init", "new" and (to a lesser degree) "create". You probably want to avoid such things in your property names. Details here.
In general, properties should represent conceptual "properties" of an object. So if you had a Person class, it might have a name property, but it wouldn't have a createNewOutfit property.
You need to access createNewFood on an instance of AppDataSorting - but you're trying to access the property on the AppDelegate-class which clearly doesn't implement it.
So you would need to create an instance of AppDataSorting and then access the property like so:
AppDataSorting *instance = [[AppDataSorting alloc] init];
instance.createNewFood = self.foodName.stringValue;
Final notes:
The docs provide a good base of information
If you don't need atomicity you should always declare properties with the nonatomic attribute
createNewFood is not a good name for a property since it suggests a method which creates new food - yet it's only meant to store data (in this case an NSString instance)

Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol while adding overlays to MKMapView

I got this error when I'm trying to add overlays to map, from one of SO answers How to prevent from "_OBJC_IVAR_$_UIPickerView._backgroundView symbol not found" error? I understood that we shouldn't use private ivar, but i didn't use any of them in my code, still I got the following error.
Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol OBJC_IVAR_$_MKPolygon._interiorPolygons
Please show me the way to solve this problem
As of XCode 4.5 the 3 variable declaration statements can be collapsed into 1
An iVar
A Property
A Synthesize
Now:
1. Synthesize
So, if old code was:
NSString* name; //in .h file
#property (nonatomic, strong) NSString* name; // in .h file
#synthesize name; // in .m file
Since 4.5 this is all that is needed is:
#property (nonatomic, strong) NSString* name; // in .h file
We can now address this iVar with either of the following:
self.name = #"john"; // used to reference the full property setter/getting - usually from outside the object
_name = #"john"; // used to reference an internal variable
This error message happened to me when the I used the iVar (notice no leading underscore):
name = #"john";
To fix change to either:
self.name = #"john"; // or
_name = #"john";
Note: I did not get this error on xcode version 4.5 (4G182) but I did on 4.5.2 (4G2008a).

How come synthesizing with an underscore is not working?

I am trying to synthesize variables in my iPhone app with
#synthesize samples=_samples;
with samples declared as
#property (strong, nonatomic) NSMutableArray *samples;
However, I get a build error claiming that _samples does not exist. Why?
Are you trying to access the _samples from outside the implementation file? ivars generated through #synthesize are not viewable by anything outside of the implementation where the #synthesize was called. So if you do something like this...
MyView *myView = [[MyView alloc] init];
myView._sample;
...you will see an error. See here for more details: https://stackoverflow.com/a/8511046/251012
.
.
.
.
EDIT: All of the below is wrong. Left, so that the comments make sense
Are you declaring your ivar's and are the names spelled correctly?
When you say something like...
#synthesize foo = _foobar;
...you need to make sure that you set the instance variable in your interface like so...
#interface MyObject : NSObject
{
NSString *_foobar;
}
#property(nonatomic,strong) NSString *foo;
#end
To be clear, when you say foo=_foobar, foo is the base name to auto-generate the getter/setter's, and _foobar is the name of the ivar. If no ivar is declared, #property will auto-generate one of the same name.
Same code is working on my side. Try to restart xcode and rebuild the project.

Strange behavior with NSString instance variable

Here is part of a class definition in an iOS program using reference counting (ARC):
#interface CapViewController : UIViewController
{
NSString *bottomBn;
NSString *topBn;
}
#property (nonatomic, strong) NSString *bottomBn;
#property (nonatomic, strong) NSString *topBn;
#end
In the implementation I synthesize them:
#implementation CapViewController
#synthesize bottomBn;
#synthesize topBn;
The problem is when I try to assign values. If I step through the following lines in a class method (first time each instance variable is being used):
bottomBn = [NSString stringWithString:#"bottomBn"];
topBn = [NSString stringWithString:#"topBn"];
After the first line has executed, the value of topBn becomes #"bottomBn" and bottomBn is nil
The second line has no impact.
If I change the order the instance variables are defined in the class, i.e.:
NSString *topBn;
NSString *bottomBn;
then the first assignment has no effect and the second assignment results in "topBn" being assigned to bottomBn.
Using local variables it works as expected:
NSString *localbottomBn = [NSString stringWithString:#"defaultbottombutton"];
NSString *localtopBn = [NSString stringWithString:#"defaulttopbutton"];
This seems bizarre behavior to me. I'd appreciate any help.
You are not setting the autoreleased strings, you should set the strings as:
self.bottomBn = [NSString stringWithString:#"bottomBn"];
self.topBn = [NSString stringWithString:#"topBn"];
I have same problems with other types and objects (even CGFloat and CGPoint). I think the problem is in debugger. Try to print you strings instead of look variables via debugger. For me NSLog function print what I expected.
I have no ideas why debugger have this unpredictable behavior (may be it's a bug), but now I prefere "NSLog debugging". It is sad.

Objective C, and NSMutableString

Header File:
#interface Picker : UITableViewController <NSXMLParserDelegate> {
NSMutableString *currentRow;
}
#property (nonatomic, retain) NSMutableString *currentRow;
#end
Implementation File:
#import "Picker.h"
#implementation Picker
#synthesize currentRow;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
currentRow = [[NSMutableString alloc] initWithString:#"VehicleYear"];
}
return self;
}
#end
After debugging this and stepping into where currentRow gets initialized with string. Step over the statement then hover over currentRow and value says "Invalid Summary".
It would seem that it gets a pointer as i get an address reference something like 0x33112 not actual memory reference.
No matter what I do I can't get a valid string in this property, so all of my comparisons are failing. What am I doing wrong?
I don't know if this has something to do with it, but if you read the documentation for the initWithString: method it returns an instance of a subclass of NSString which may or may not be an instance of NSMutableString
Try this instead, it will do what you want:
currentRow = [#"VehicleYear" mutableCopy];
Also, 99% of the time you want a string property of a class you want to declare it as:
#property(readwrite,copy)NSString *name;
If you declare a readwrite string property as anything other than copy then whoever sets it can change their string and affect your object's internal state, which is usually not what you want. If the original string is not mutable then its copy method does a retain anyway so there is no performance lost in the case where it mattered.
If you want a mutable string internally that no external user can change you probably want to declare the property like this:
#property(readwrite,copy)NSString *name;
And then implement -name and -setName: yourself so that you can call -mutableCopy to set it and -copy in the getter so that they cannot change your internal state. I have written extensively about this on my blog.
Note that this
#property(readwrite,copy)NSMutableString *name;
Doesn't do what anyone wants when you #synthesize the accessors as the setter invokes -copy and gets an NSString which is not an NSMutableString as a result.
I sometimes get incorrect information from the visual debugger. In the gdb console, you can type "print-obj currentRow" and it should give you better information.
One thing to make sure is that you're debugging a build with optimizations turned off (i.e., Debug, not Release, configuration), otherwise the code doesn't map exactly onto the compiled instructions.