Calling method in object gives SIGBART - iphone

Simple question, but this gives me an error and I can't seem to resolve it.
In my object (UIViewController) I have declared a method in the .h
-(void)setCurrentLoc:(CLLocation *)loc;
and in the .m
-(void)setCurrentLoc:(CLLocation *)loc
{
currentLocation = loc;
}
All good. But this is how I initiate this object (which works fine) but when I call setCurrentLoc: it gives SIGBART
.h
IBOutlet VectorViewController *vectorView;
.m
vectorView = [[VectorViewController alloc] init];
...
//In another method I call:
[vectorView setCurrentLoc:location]; // Error/SIGBART line
Is there something I missed? Maybe not making it global or something?
Error:
-[UIView setCurrentLoc:]: unrecognized selector sent to instance 0x841cab0

-[UIView setCurrentLoc:]: unrecognized selector sent to instance 0x841cab0
This means that you are sending the message to a pointer that is no longer pointing at your VectorViewController, but is now pointing at a UIView. This usually happens when the object has been autoreleased or released and the memory re-used.
Check carefully what happens between when you create vectorView and when you call it again in your other method. You seem to be setting and accessing the instance variable directly - you should probably be accessing it via properties (hard to be specific without knowing if you are using ARC or not) and making sure those properties are declared appropriately.

Based on the code you've written, you don't need to provide a setCurrentLoc method, use a property instead and synthesize instead.
in your VectorViewController class, use:
#property (nonatomic, retain) IBOutlet CLLocation * currentLocation;
in your #implementation, add:
#synthesize currentLocation;
and in your dealloc method, add:
self.currentLocation = nil;
Leave your existing setCurrentLocation call as is.

Related

iOS error on array initialisation

I'm trying to initialise an array of Photos, and am doing so like this:
NSMutableArray *photoList = [[NSMutableArray alloc] init];
self.photos = photoList;
But when this line of code runs, I get this error:
'NSInvalidArgumentException', reason: '-[Project setPhotos:]: unrecognized selector sent to instance 0xee8e310'
I've spent about three hours trying to find a fix but couldn't, can anybody tell me what to do?
It seems to me that you haven't created a property photos and if you have then it would also seem that this property is not #synthesize'd in your implementation, maybe you are using #dynamic, in which case it is up to you to create a - (void)setPhotos:(NSMutableArray*)photos; method
self does not have a property called photos
You need to add #property (nonatomic, strong) NSArray *photos; in your .h file, before the #end
and in the .m file, #synthesize photo;
This line of code:
self.photos = photoList;
gets turned into this line
[self setPhotos:photoList];
by the compiler - the dot notation is what is called "syntatic sugar" as is just makes it easier to type, it doesn't really shorten the code.
If you have created your own getters and setters (ie)
- (NSMutableArray *)photos;
- (void)setPhotos:(NSMutableArray *)myPhotos
Then you can use that sugar even though you don't have a property called "photos" - although this is considered a misuse of the feature (I show it for comparison purposes).
When you create a property named photos:
#property (nonatomic, strong) NSMutableArray *photos;
the compiler will generate an ivar for you using the same name, but not create the getters and setters. The line:
#synthesize photos;
asks the compiler to do a getter (in all cases) and a setter (if the property is read write). If you do not provide a #synthesize statement, the compiler normally complains, so people should be observing these warnings.
You can see in the error that you have no setPhotos, thus your problem can be fixed quite easily.
Seems like you haven't written a setter method for photos.
in your .h
#property (strong, nonatomic) NSArray * photos;
in your .m (if not using xcode 4.4)
#synthesize photos;
or you could just try writing it like this
photos = [NSArray arrayWithArray:photoList];
For reference if you use [self setMyArray:array] or self.array = myArray
Then you are using the setter method, which is something you probably want to do. If you just point array = myArray, you would be pointing to myArray and if it were released your pointer would point in to the abyss. It's good to not to do that, not using the setter means you are accessing the variable photos directly and this may not be what you want.
Whoops, I'd used #dynamic photos instead of #synthesize photos

singleton, public, or global variable use

I have searched and tried every example regarding singleton, public, and global variables in stack overflow on this subject. I'm making a mistake some where. I have a settings variable called strIP that is part of a textField and is declared in my secondViewController.h. I want this variable to used in a class called myWSupdate.m. It's just one variable I wanna pass it to a connection string. this compiles correctly but the app crashes on run. What am I doing incorrectly?
error from complier:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[SecondViewController sharedIP]: unrecognized selector sent to class 0x6403c'
secondViewController.h
#interface SecondViewController : UIViewController
{
UITextField *ipAdd;
NSString *strIP;
}
#property (nonatomic, retain) IBOutlet UITextField *ipAdd;
#property (retain) NSString *strIP;
+(SecondViewController*)sharedIP;
then I call it in myWSupdate.m:
#import "SecondViewController.h"
/* Implementation of the service */
#implementation myWSupdate
- (id) init
{
if(self = [super init])
{
SecondViewController* IP = [[SecondViewController sharedIP]init];
NSLog(#"the test has %#", IP.strIP);
}
}
#end
Since strIP belongs to a SecondViewController, you need to reference it as part of that object.
How to do that depends on the relationship between SecondViewController and myWSupdate. (For example, if the controller creates a myWSupdate object, you could pass the variable as part of the init.)
The fact that it's marked public doesn't change the fact that it's an instance variable and therefore needs to be used in connection with an instance of its class.

How do I create property for subclass of Apple's class

I am trying to access an instance of SVSegmentedControl
It's a subclass of UIControl.
I created that instance during viewDidLoad
SVSegmentedControl *mySC = [[SVSegmentedControl alloc] initWithSectionTitles:[NSArray arrayWithObjects:#"Normal", #"Limosine", #"Any", nil]];
It does have a method - (void)segmentedControlChangedValue:(SVSegmentedControl*)segmentedControl { which I will be able to access the instance when the value is changed. But how do I access the instance(mySC) at other parts of the code?
Set a property in your UIViewController, and instead of creating a new instance variable, set the property to the newly initialised segmented controller. And from there on you can access it outside the viewDidLoad's scope.
Edit...
You really need to learn how to propertize / setter & getter a variable rather than asking people to post code for you.
Below the } in the header file:
#property (nonatomic, retain) SVSegmentedControl *control;
Top of the implementation file
#synthesize control;
To set it:
self.control = [[[SVSegmentedControl alloc] init...] autorelease];
It should be set to nil in the dealloc method.

Crash when accessing a NSMutableArray member variable

I'm having some trouble with a NSMutableArray. I'm sure i'm doing something wrong with the allocation of the NSMutableArray but it's not obvious to me being an iPhone newbie. When i run the code below i can add the object MyObject to the array objects_ and set the name etc. The NSLog displays the correct data.
But when i try to access the objects_ member from the function printObject i get a SIGABRT. Looks like the memory has been deallocated or something?
Any help appreciated.
#interface MyObject : NSObject {
NSString *name;
}
-(void) SetName:(NSString*) name_str;
-(NSString*) GetName;
#end
#interface ObjectListViewController : UITableViewController {
NSMutableArray* objects_;
}
-(void) initTableData;
#end
#implementation ObjectListViewController
- (void)initTableData {
objects_ = [[NSMutableArray alloc] initWithCapacity:10];
MyObject *obj = [MyObject alloc];
[obj SetName:#"Test"];
[objects_ addObject:obj];
MyObject* testObj = (MyObject*)[objects_ objectAtIndex:0];
NSLog([testObj GetName]);
}
- (void)printObject {
MyObject* testObj = (MyObject*)[objects_ objectAtIndex:0];
NSLog([testObj GetName]);
}
We can eliminate the lack of an init call on MyObject as the cause of the crash as in this case it will be benign. Calling init on NSObject will just return self, so calling it in this case won't change the behaviour. So I don't think the first two answers here will make any difference:
An object isn’t ready to be used until it has been initialized. The init method defined in the NSObject class does no initialization; it simply returns self.
Chuck correctly points out that init is a fundamental step in object allocation and initialization and you should be calling it when you allocate MyObject.
I am not sure the third answer is correct either. I don't really see how adding synthesise on the objects_ array will make any difference. You haven't defined it as a property, and I don't really see why you would need to, given it is just data internal to the class.
The comment on the question Well, for starters, you never define printObject in the #interface. from eykanal doesn't really help you either, because you must be calling printObject internally, otherwise you wouldn't be hitting the crash.
Reading the through the code, I can't see an obvious error. The retain count on objects_ after initTableData finishes should be one, the retain count on the instance of MyObject should also be one. So I think there must be some other code that is releasing objects_ elsewhere?
I am assuming it is crashing on the objectAtIndex call? Is there any info in the console? What does the call stack look like?
MyObject *obj = [MyObject alloc];
should be:
MyObject *obj = [[MyObject alloc] init];
#interface ObjectListViewController : UITableViewController {
NSMutableArray* objects_;
}
#property (nonatomic, retain) NSMutableArray *objects_;
-(void) initTableData;
-(void) printObject;
#end
add the synthesize in the implementation
#implementation ObjectListViewController
#synthesize objects_;
Here are some issues in your code:
You never initialise your MyObj object. Although it inherits directly from NSObject and NSObject is documented to do nothing except return self, you never know if other stuff happens behind the scenes, so put it in just to eliminate the posssibility.
Your methods don't follow the normal naming conventions. method names should begin with a lower case letter and "get" should only be used when passing back data by reference through the parameters as in e.g. NSData -getBytes:length:. Your getter and setter should be -name and -setName: respectively. This may seem like a minor nitpick, but it'll help you later on if you start to use KVO and KVC.
Never do NSLog(someStringVariable) always NSLog(#"%#", someStringVariable). As you have it now, if the object's name contains a percent formatting sequence e.g. %#, %d, %s etc, your program will crash on the NSLog. However, this is not the cause of your current problem - it would be crashing on the NSLog in -initTableData
you don't need to cast the result of -objectAtIndex:
Having said all that, I can't see anything that would cause the particular issue you have. It may be that the getter or setter for the name in MyObject is incorrect. Please post them.

Passing a Property to a function and setting the value to be retained

I have two properties setup as ViewControllers that each use different NIB file. (Male and Female Models, will function the same but are setup visually different.) I want to have one function to create the ViewController based on the NIB Name and ViewController I pass in.
What's happening is the ViewController property is not being retained. If I add the actual property name within the function and set it, the viewController is set and retains the ViewController. Here is what I have in the .m file (Only showing what is needed to get help on.) I've kept in the two comment lines that I tried to do determine where the problem was.
#synthesize femaleModelViewController;
#synthesize maleModelViewController;
- (void) loadModelViewControllerWithModelType:(NSString*) model ModelView:(ModelViewController *)modelViewController {
ModelViewController *viewController = [[ModelViewController alloc] initWithNibName:model bundle:nil];
// [self setFemaleModelViewController:viewController]; // I don't want to set the property here, I want to be able to pass it as an argument.
modelViewController = viewController;
// [modelViewController retain]; // I even tried to retain it do see if would but it doesn't.
[viewController release];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadModelViewControllerWithModelType:#"FemaleModel" ModelView:femaleModelViewController];
[self loadModelViewControllerWithModelType:#"MaleModel" ModelView:maleModelViewController];
}
In the .h file my Properties are setup like so:
#property (nonatomic, retain) ModelViewController *femaleModelViewController;
#property (nonatomic, retain) ModelViewController *maleModelViewController;
Are you trying to assign a new ModelViewController to maleModelViewController and femaleModelViewController? If so, you're going about it the wrong way.
Frankly, I'd do away with the loadModelViewControllerWithModelType:modelView: method altogether. All you would need to do in viewDidLoad is this:
maleModelViewController = [[ModelViewController alloc] initWithNibName:#"MaleModel"];
femaleModelViewController = [[ModelViewController alloc] initWithNibName:#"FemaleModel"];
(This assumes that maleModelViewController and femaleModelViewController are the instance variables backing the properties of the same name.)
When you pass in maleModelViewController and femaleModelViewController, you're not passing a reference to those variables, you're passing their values. Since they haven't been initialized, all you're doing is passing in nil. To do what you're trying to do, you'd need to pass a pointer to the variables (i.e. declare the parameter as ModelViewController **, pass it in as &maleModelViewController and &femaleModelViewController and assign it using *modelViewController = viewController. If you're used to using pass-by-reference friendly languages like C# or Java, you should read up on how it works in C. (The rules are the same in Objective-C as in C).
HOWEVER, that is still complete overkill for what you're trying to do here.
Also, your code would still not work because you turn around and release viewController. This would cause it to be immediately deallocated, since the only reference you had to it came from when you alloced it. You would be assigning a dead reference that would crash your program as soon as you tried to use it.