I am new to programming, and i decided to start off with using Xcode and Obj-C.
I'm making a tabbed application where the second view controller contains the map that is supposed to zoom to the users location. I guess i just cant get the code right, when i try to run the app in iOS simulator it just crashes when i open the second view controller.
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
Within #autoreleasepool i get a "Thread 1: signal SIGABRT" on every run.
This is the output i get when i open the second view controller
2013-08-05 21:31:26.271 placerate[56730:c07] Couldn't find default.styleproto in framework
2013-08-05 21:31:26.277 placerate[56730:c07] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x98a1120> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key mapView.'
*** First throw call stack:
(0x16b3012 0x14d8e7e 0x173bfb1 0xf84e41 0xf065f8 0xf060e7 0xf30b58 0x63a019 0x14ec663 0x16ae45a 0x638b1c 0x4fd7e7 0x4fddc8 0x4fdff8 0x4fe232 0x51f8c9 0x51f704 0x51dbda 0x51da5c 0x51f647 0x14ec705 0x4202c0 0x420258 0x642ff4 0x14ec705 0x4202c0 0x420258 0x4e1021 0x4e157f 0x4e1056 0x646af9 0x14ec705 0x4202c0 0x420258 0x4e1021 0x4e157f 0x4e06e8 0x44fcef 0x44ff02 0x42dd4a 0x41f698 0x2500df9 0x2500ad0 0x1628bf5 0x1628962 0x1659bb6 0x1658f44 0x1658e1b 0x24ff7e3 0x24ff668 0x41cffc 0x22fd 0x2225)
libc++abi.dylib: terminate called throwing an exception
(lldb)
This is the output under the "Auto" pane :
argc = (int)1
argv = (char **)0xbffff3b4
SecondViewController.h :
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface SecondViewController : UIViewController
<MKMapViewDelegate>
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
- (IBAction)zoomIn:(id)sender;
- (IBAction)changeMapType:(id)sender;
#end
SecondViewController.m :
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (IBAction)zoomIn:(id)sender {
MKUserLocation *userLocation = _mapView.userLocation;
MKCoordinateRegion region =
MKCoordinateRegionMakeWithDistance ( userLocation.location.coordinate, 50, 50);
[_mapView setRegion:region animated:NO];
}
- (IBAction)changeMapType:(id)sender {
if (_mapView.mapType == MKMapTypeStandard)
_mapView.mapType = MKMapTypeSatellite;
else
_mapView.mapType = MKMapTypeStandard;
}
- (void)mapView:(MKMapView *)mapView
didUpdateUserLocation:
(MKUserLocation *)userLocation
{
_mapView.centerCoordinate =
userLocation.location.coordinate;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_mapView.showsUserLocation = YES;
_mapView.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I've followed a tutorial on the matter - so as you might have noticed, this is pretty greek to me. I'll be happy to supply additional information on the problem. Thanks in advance,
kind regards
Yngve
EDIT:
I created a new project and i recycled some of the code, for some reason it just worked. I believe the different answers and solutions gave me a heads up to pay more attention when working with programming. This is my first project, so i expect i might run into some more trouble, thank you all for taking the time to answer my question. (I actually find code exciting now)
Yngve
Looks like you just need to set the class of the second view controller to SecondViewController in the inspector pane of your storyboard. It's still set to a stock UIViewController.
Sounds like the missing styleproto files might be the issue, see this SO answer: iOS6 Simulator MKMapKit "Couldn't find default.styleproto in framework"
Are you using a Storyboard or NIB? If so, you might want to see this SO answer and make sure you set the right custom class in IB: NSInvalidArgumentException isKindOfClass
For me mapView will sometimes throw exceptions in the simulator when you execute this line of code
_mapView.showsUserLocation = YES;
Restarting Xcode and clearing derived data is what fixes it for me when it gets in this state. Resetting simulator does nothing.
Related
While trying to run my tab-bar app with many different features such as UITableView and mapview with a annotation, I recently added a webview on my first tab in my firstviewcontroller. As far as I know, there's nothing wrong with the coding there, though ever since I tried adding the webview on my first tab I keep getting the breakpoint/error while trying to run the app : Thread 1: signal SIGBRT.
I've read around some, and someone said that if I change mi xib file /storyboard's deployment to iOS 5.0 instead of 6.0 (wich I'm currently using) and not having "Use Autolayout" checked it should get rid of it. Though It didn't. Any thoughts or solutions to this?
Here's the coding for my firstviewcontroller.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#end
firstviewcontroller.m
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize webView;
- (void)viewDidLoad
{
NSString *website = #"http://www.google.com";
NSURL *url = [NSURL URLWithString:website];
NSURLRequest *requestUrl = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestUrl];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
main.m :
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); // <--- HERE's where it says SIGBRT
}
}
All output:
2013-01-04 11:27:06.697 My Corp[784:13d03] Unknown class ViewController in Interface Builder file.
2013-01-04 11:27:06.716 My Corp[784:13d03] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<FirstViewController 0x808fbf0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myWebView.'
*** First throw call stack:
(0x1800012 0x11c5e7e 0x1888fb1 0xc72711 0xbf3ec8 0xbf39b7 0xc1e428 0x32a0cc 0x11d9663 0x17fb45a 0x328bcf 0x1ede37 0x1ee418 0x1ee648 0x1ee882 0x20fed9 0x20fd14 0x20e1ea 0x20e06c 0x20c1cc 0x20c9b6 0x1f0753 0x1f0a7b 0x1f1964 0x154877 0x15b5a3 0x153eed 0x13db56 0x13ddbf 0x13df55 0x146f67 0x10afcc 0x10bfab 0x11d315 0x11e24b 0x10fcf8 0x1cc9df9 0x1cc9ad0 0x1775bf5 0x1775962 0x17a6bb6 0x17a5f44 0x17a5e1b 0x10b7da 0x10d65c 0x289d 0x27c5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
The mistake you have done was clearly stated in the crash report
[<FirstViewController 0x808fbf0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myWebView.'
To solve that go to your XIB of that Class right click on the File owner located on the left side pane of InterfaceBuilder. You will find an object with name myWebView with yellow warning icon, click remove on that outlet connection and compile your code. You have connected the outlet and later you remove the IBOutlet in the code and forget to remove the connection in the XIB.
set
UIWebViewDelegate in .h file and in xib attach delegate of webview
I'm trying to share a string between two views on my iPhone project. It currently works if I use the actual #"something here" for the string, but if I want to use something like label.text, it doesn't even though it is still a string.
I'll show you what I have to make it clearer.
First View: Info_ViewController.h
#import <UIKit/UIKit.h>
#interface Info_ViewController : UIViewController {
IBOutlet UITextField *locationField;
}
#property (nonatomic, retain) NSString *locationString;
+ (id)sharedInfoVC;
#end
First View: Info_ViewController.m
#import "Info_ViewController.h"
static Info_ViewController *sharedInfoVC = nil;
#implementation Info_ViewController
#synthesize locationString;
#pragma mark Singleton Methods
+ (id)sharedInfoVC {
#synchronized(self) {
if (sharedInfoVC == nil)
sharedInfoVC = [[self alloc] init];
}
return sharedInfoVC;
}
- (id)init {
if (self = [super init]) {
locationString = [[NSString alloc] initWithString:locationField.text]; //This is there part I mentioned earlier, when using #"something" instead of locationField.text works.
}
return self;
}
Second View: Confirm_ViewController.m
#import "Confirm_ViewController.h"
#import "Info_ViewController.h"
#implementation Confirm_ViewController
- (IBAction)buttonZ:(id)sender
{
Info_ViewController *infoVCmanager = [Info_ViewController sharedInfoVC];
locationLabel.text = infoVCmanager.locationString;
}
I put it under a button for now, but it will eventually be under viewDidLoad.
If you replace locationField.text with a string (#"blahblahblah") it won't crash and works.
When it crashes I get the error: Program received signal: "SIGABRT"
EDIT: I tried changing
initWithString:locationField.text
to
initWithFormat:#"%#",locationField.text
and now it my label in the second view prints "(NULL)"
Thanks for taking the time to give advice, I really appreciate it.
It is an error to pass nil as the format string to -[NSString initWithString].
So how are you passing nil? You actually have two instances of Info_ViewController. You have the one instance which is the normal part of your app, and then you also have a second instance which is your "singleton" (which really isn't a singleton any more).
So in your "singleton" instance, the UITextField is nil (and will always be nil) and so locationField.text is nil and you are passing that to initWithString:, which is a crash. In fact the "singleton" isn't even fully baked as view controller's go.
If you want a singleton to share data elsewhere in your app, it really should not be a Info_ViewController or any type of view controller. It should be of some other class that you use to manage your data. I would create another class and implement that as a singleton.
Hope that helps you understand what's happening here.
Pre-pend "self." to your location string.
self.locationString = [[NSString alloc] initWithString:locationField.text];
From what I understand of your code, you have got the value for locationString when you from the textfield when you initialize the viewController. At this point of time, your textfield would not be visible. After it becomes visible and you enter something, you don't have the code to store it to locationString.
What you should do is wait for Info_ViewController object to be initialized and displayed. Then on the press of some button or some other event, assign locationLabel.text from the locationString or even directly from locationField.text.
I would provide code, but I have no clue as to how you are structuring this. If you still need help, please provide the details.
i am getting this error "message sent to deallocated instance 0x141dafb0" its comming from a UIBarButtonItem when its beeing pressed on the application. any help would be greatly appreciated
Error:
*** -[PeerConnection performSelector:withObject:withObject:]: message sent to deallocated instance 0x14143ff0
PeerConnection.h
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
#interface PeerConnection : NSObject <GKPeerPickerControllerDelegate, GKSessionDelegate> {
UIBarButtonItem *StartConnection;
}
- (IBAction) StartConnectionAction;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *StartConnection;
#end
PeerConnection.m
#import "PeerConnection.h"
#implementation PeerConnection
#synthesize StartConnection;
- (IBAction) StartConnectionAction {
NSLog(#"Start Connection to the other IPhones");
[StartConnection release];
}
- (void)dealloc {
[super dealloc];
}
#end
i have enabled Zombie and that is all its giving to me
Don't release your StartConnection button until -dealloc. Releasing that bar button item in -StartConnectionAction is your problem--anything the UI tries to do with it after that will call a zombie.
In your case, you have released the StartConnection object. Now, when the automatic dealloc is called, the reference was not found (as already removed) and hence you got the error.
I had the same error, but was using a singleton with autorelease on shared method, took off autorelease from there and added on it's dealloc , and all works fine now.
Old Thread; But thought I might add.
If your app isn't using ARC; Use The Analyse Feature to find all the problems that may arise due to releasing/retaining objects.
Shortcut is command + shift + B
Totally useful !
This may be due to access of the instance that is already removed during GC. The error occurs in a case when you use autorelease.
ThePlannerAppDelegate *delg = [(ThePlannerAppDelegate *)[[UIApplication sharedApplication] delegate] autorelease];
Now this is most likely the GC will destroy the reference although delg points to the main window delegate.
My point is use autorelease safely.
Important: The error will occur when a message will be sent to an dead reference.
I'm working on an application with three tabs plus a small view in which I created a sort of TopBar that contains some info and some buttons.
In the main application delegate I define:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
...
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
//here we add the topBar:
topBarViewController = [TopBarViewController instance];
topBarViewController.appDelegate = self;
[window addSubview:topBarViewController.view];
...
}
- (void)showReplyView
{
self.tabBarController.selectedViewController =
[self.tabBarController.viewControllers objectAtIndex:2];
}
as you can see I set the .appDelegate in the topBar to make some call back in the code of the topBar (ie: when I want to change the tab currently visualized)
Now in my TopBarViewController.h I have:
#interface TopBarViewController : UIViewController {
MyAppDelegate *appDelegate;
...
}
#property (nonatomic,retain) MyAppDelegate *appDelegate;
-(void)testMethod;
and in the .m file:
#implementation TopBarViewController
#synthesize appDelegate;
...
-(void)testMethod{
[appDelegate showReplyView];
}
...
When I build the project the compiler tell me that the showReplyView method doesn't exist.
I tried everything and I'm sure that there are no typo errors...
Is it possible that I can't reference to the delegate?
Thanks to anyone would help me...
I found the problem:
in the TopBarViewController.h I was declaring #class MyAppDelegate; since I couldn't make an import (avoid the loop).
So the compiler was not able to find out which methods were declared.
To solve it I import the #import MyAppDelegate.h directly in the TopBarViewController.m!
Thanks anyway for the help!
Have you defined showReplyView in the #interface for MyAppDelegate?
I have two Objective-C classes that inherit from the UIViewController and am trying a different approach at learning how to interact with the iPhone's address book. The example Apple provides assumes that everything is in one class, but this isn't the way I need it done. My objective would be to have the address book view close after a person is selected. Please have a look and let me know how i can accomplish this without having CallerClass implement ABPeoplePickerNavigationControllerDelegate. Thanks!
-- edit --
What it seems to be boiling down to is the [self dismissModalViewControllerAnimated:YES]; does not have any effect in CalleeClass.m. I still can't seem to get a reaction to close the address book from this command.
CallerClass.m
#import "CallerClass.h"
#implementation CallerClass
- (IBAction)openAddressBook {
CalleeClass *cc = [[CalleeClass alloc] init];
[self presentModalViewController:[cc doIt] animated:YES];
}
CalleeClass.h
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#interface CalleeClass : UIViewController <ABPeoplePickerNavigationControllerDelegate> {
NSString *name;
}
-(ABPeoplePickerNavigationController *)doIt;
#property (nontoxic, retain) NSString *name;
#end
CalleeClass.m
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import "CalleeClass.h"
#implementation CalleeClass
#synthesize name;
… (default ABPeoplePickerNaviationControllerDelegate implementation outside of what's listed)
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {}
return self;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
self.name = (NSString *)ABRecordCopyValue(person,kABPersonAddressProperty);
[self dismissModalViewControllerAnimated:YES];
return NO;
}
-(ABPeoplePickerNavigationController *)doIt {
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
return picker;
}
#end
If the problem is, as you say, that [self dismissModalViewControllerAnimated:YES] has no effect if called from CalleeClass, this is because dismissModalViewControllerAnimated: must be called on the presenting view controller (i.e., the one on which you called presentModalViewController:Animated:. Since you don't have a reference to your CallerClass instance in CalleeClass, this doesn't work.
Fortunately, as the documentation for dismissModalViewControllerAnimated: notes:
If you call this method on the modal view controller itself, however, the modal view
controller automatically forwards the message to its parent view controller.
So this should work:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
self.name = (NSString *)ABRecordCopyValue(person,kABPersonAddressProperty);
[peoplePicker dismissModalViewControllerAnimated:YES];
return NO;
}
Once you have identified the contact you want to act on you can just pass around the int32 recordID, although as mentioned in the API docs you should probably also use the composite name since as you will notice the recordID is a simple value that starts with "1" and you could run into trouble if your database was restored to a phone with new contacts in old recordID values. Every time you need to access something from the Address Book you do need to create the phone book but you can close it right after, so with recordID you can open, get what you want and then close it. My suggestion is just use the picker like a normal view controller up to the point where you get the recordID, dismiss it, then keep that unique identifier. Use picker again when you need to find a new recordID.