passing parameter in ios5 storyboard segue + UITableview - xcode

I was to pass a NSString from RootViewController(UITableViewController) to DetailViewController .
t RootViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
DetailViewController *detailViewController = segue.destinationViewController;
detailViewController.name = #"foo";
}
DetailViewController.h:
NSString *name;
#property (nonatomic,strong) NSString *name;
DetailViewController.m
#synthesize name = _name;
NSLog(#"%#", name);
The result of NSlog is null. Appreciate for any hint. Thanks a lot.

I can't really see when you are executing your nslog. So i'm thinking you ask for the name before you are setting it.
And another thing. If you write:
#synthesize name = _name;
you should use this too:
NSLog(#"%#", _name);

you can view the sample passing data from cell to detailViewController at YouTube.

Related

Using and updating a NSMutableString in AppDelegate for two viewcontrollers

I have a NSMutableString defined in my AppDelegate.h file.
//AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>{
#public
NSMutableString *nidForDetailDisplay;
}
Then I set this string in my ViewController.m file. I am storing a string (nidForDetailDisplay) to pass from a tableview to detailview.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
rowNumber = indexPath.row;
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
// this is where I set the string to a string of text
appDelegate->theNidForDetailDisplay = [arrayOfNids objectAtIndex:rowNumber];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIViewController *detailViewController;
DetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"detail"];
[self.navigationController pushViewController:detail animated:YES];
}
In ViewController, when I log theNidForDetailDisplay, I get the correct string.
Next, I try to access this updated NSMutableString (nidForDetailDisplay) in the subsequent DetailViewController
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSMutableString *storyid;
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate->theNidOnDetailDisplay = storyid;
}
However, when I print the string (storyid) or (theNidOnDetailDisplay) they both return null.
Am I missing something here? Should I be using instance variables?
Thanks in advance.
Don't use your AppDelegate to pass data. Add a property to the detail view controller and assign the value to the property.
on DetailViewController:
#property (nonatomic) NSMutableString * nid;
The assign it before you present:
DetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"detail"];
detail.nid = [arrayOfNids objectAtIndex:rowNumber];
[self.navigationController pushViewController:detail animated:YES];

How to pass value to another controller view in Xcode

How do i get the value from different UIViewController in xcode storyBoard?
I end up using prepareForSegue method.
first i create a string in my third view controller.
#property (strong,nonatomic) NSString* stringFromSecondView;
Then I gave the push segue an ID called "getDate" and in my second view class use this code below and remember to import the thirdviewcontroller.h
#import "thirdViewController.h"
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"getDate"]){
NSString *intro = _myDate.text;
thirdViewController *vc = [segue destinationViewController];
vc.stringFromSecondView = intro;
}
}
Now back to my thirdViewController.m
_myLabel.text = stringFromSecondView;
In your second VIew Controller
- (IBAction) btnPressToBringThirdView : (id) sender
{
ThirdViewController* newObject = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
newObject.labelString = #"whatever text you want";
[self.navigationController pushViewController:newObject];
[newObject release];
}
In your third viewcontroller in .h file
#property (nonatomic, retain) NSString* labelString;
in .m file
- (void)viewDidLoad
{
[super viewDidLoad];
yourLabel.text = labelString;
}
ViewController *secondview=[[ViewController alloc]init];
secondview.your var here= secondview.your var here+100;//whate you var to change if NSintager
///to save your var
[[NSUserDefaults standardUserDefaults]setInteger:secondview.your var here forKey:#"your key to save"];

MapKit pin title not showing

The location is working but the title isn't appearing, most strange.
location.latitude = (double) 51.501468;
location.longitude = (double) -0.141596;
// Add the annotation to our map view
MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"ABC" andCoordinate:location];
[self.mapView addAnnotation:newAnnotation];
// [newAnnotation release];
MapViewAnnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MapViewAnnotation : NSObject <MKAnnotation> {
NSString *title;
CLLocationCoordinate2D coordinate;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;
#end
and MapViewAnnotation.m
#import "MapViewAnnotation.h"
#implementation MapViewAnnotation
#synthesize title, coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
title = ttl;
coordinate = c2d;
return self;
}
#end
[newAnnotation release] is remmed out to keep the ARC happy :-)
Any ideas?
This did the trick:
[mapView selectAnnotation:newAnnotation animated:YES];
previously the title would only show if you clicked on the Pin.
you call annotation delegates refer this link, mapkit-example-in-iphone
That code looks fine (except for the non-standard implementation of the init method).
The most likely reason the title (callout) isn't appearing is that in your viewForAnnotation delegate method, you are not setting canShowCallout to YES (it defaults to NO).
In the viewForAnnotation delegate method, after you create the MKAnnotationView, set canShowCallout to YES.
Unrelated to the title/callout not showing, the init method in your MapViewAnnotation class should be implemented like this:
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
self = [super init];
if (self) {
title = ttl;
coordinate = c2d;
}
return self;
}

EXC_BAD_ACCESS when I close my window, which is also my application's delegate

I wrote a Cocoa Application and I got EXC_BAD_ACCESS error when I'm closing an application window. I read that this error usually means problems with memory, but I have ARC mode on and I don't need care about releasing e.t.c. (xCode forbids me to call this functions and manage memory automatically).
Error is pointing at line return NSApplicationMain(argc, (const char **)argv); in main function.
Here's my application's code:
.h file:
#interface MainDreamer : NSWindow <NSWindowDelegate>
{
NSTextField *dreamField;
NSTableView *dreamTable;
NSImageView *dreamview;
NSMutableArray *dreamlist;
NSMutableArray *dataset;
}
#property (nonatomic, retain) IBOutlet NSTextField *dreamField;
#property (nonatomic, retain) IBOutlet NSTableView *dreamTable;
#property (nonatomic, retain) IBOutlet NSImageView *dreamview;
#property (nonatomic, retain) IBOutlet NSMutableArray *dreamlist;
#property (nonatomic, retain) IBOutlet NSMutableArray *dataset;
#property (assign) IBOutlet NSWindow *window;
#end
.m file:
#implementation MainDreamer
#synthesize window;
#synthesize dataset;
#synthesize dreamField;
#synthesize dreamlist;
#synthesize dreamview;
#synthesize dreamTable;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
NSString *applicationPath = [[NSBundle mainBundle] bundlePath];
NSString *filename = [applicationPath stringByAppendingPathComponent:#"dreams"];
NSLog(self.description);
dreamlist = [[NSMutableArray alloc] init];
dataset = [[NSMutableArray alloc] init];
dataset = [NSKeyedUnarchiver unarchiveObjectWithFile:filename];
if([dataset count] != 0) {
int i = 0;
while (i < [dataset count]) {
Dream *dr = [[Dream alloc] init];
dr = [dataset objectAtIndex:i];
[dreamlist addObject: dr.dreamname];
i++;
}
}
[dreamTable reloadData];
}
-(void)applicationWillTerminate:(NSNotification *)notification{
NSString *applicationPath = [[NSBundle mainBundle] bundlePath];
NSString *filename = [applicationPath stringByAppendingPathComponent:#"dreams"];
[NSKeyedArchiver archiveRootObject:dataset toFile:filename];
NSLog(#"finish");
}
- (void) mouseUp:(NSEvent *)theEvent{
long index = [dreamTable selectedRow];
Dream *dr = [[Dream alloc] init];
dr = [dataset objectAtIndex:index];
dr.dreampicture = dreamview.image;
[dataset replaceObjectAtIndex:index withObject:dr];
NSLog(self.description);
}
- (void) tableViewSelectionDidChange: (NSNotification *) notification{
long row = [dreamTable selectedRow];
Dream *dr = [[Dream alloc] init];
dr = [dataset objectAtIndex: row];
if(dr.dreampicture != NULL)
dreamview.image = dr.dreampicture;
NSLog(#"selected row changed");
}
Class "Dream":
#interface Dream : NSObject <NSCoding>
{
NSString *dreamname;
NSImage *dreampicture;
}
#property (retain) NSString* dreamname;
#property (retain) NSImage* dreampicture;
-(id)initWithCoder:(NSCoder *)aDecoder;
-(void)encodeWithCoder:(NSCoder *)aCoder;
#end
What is wrong, why EXC_BAD_ACCESS occurs?I remind that I have xCode 4 with Automatic Reference Counting (ARC)
Thanks
UPDATE
I used Profile to find zombie event. So I found out this: An Objective-C message was sent to a deallocated object(zombie( at adress 0x108d85230)
Responsible Caller - [NSApplication(NSWindowCache) _checkForTerminateAfterLastWindowClosed: saveWindows:]
I had this function in code:
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender{
return TRUE;
}
However after I putted it in comments, this zombie event continue to occur.
The crash is caused by the fact that you made the window your application's delegate. When you close the window, that is the last release that kills it off, and if it's the last window you had up, it causes the application to ask its delegate whether it should quit. Since the window you just killed off is the application's delegate, you get that crash.
Longer explanation and suggestion of solution in my answer on your subsequent question.
This is wrong:
dataset = [[NSMutableArray alloc] init]; // WRONG
dataset = [NSKeyedUnarchiver unarchiveObjectWithFile:filename];
Why? You first allocate an empty array, and store that in the instance variable dataset. But in the next line, you replace the empty array with whatever +unarchiveObjectWithFile: returns. Why is this a problem? Well, if you read the docs, you'll see that it returns nil if the file is not found. This means that you now replace the empty array with nil, and all messages you send to dataset will be ignored (messages to nil are silently ignored in Objective-C)
I assume you actually want load the dataset from file, and only if that failed, start with an empty dataset:
dataset = [NSKeyedUnarchiver unarchiveObjectWithFile:filename];
if (dataset==nil) dataset = [[NSMutableArray alloc] init];
You have a similar error later on:
Dream *dr = [[Dream alloc] init]; // WRONG
dr = [dataset objectAtIndex:index];
You create a Dream object, and then replace it immediately with something from the dataset. What you actually want to do is:
Dream *dr;
dr = [dataset objectAtIndex:index];
or shorter:
Dream *dr = [dataset objectAtIndex:index];
Then again, you could replace the while loop with a fast-enumeration-style for loop:
for (Dream *dr in dataset) {
[dreamlist addObject: dr.dreamname];
}
Finally, to get to a point, I don't think the EXC_BAD_ACCESS actually occurs in main.h. I assume you use Xcode 4. Please use the thread/stack navigator in the right sidebar when debugging to find the actual position where the error occurs.
It could be that the error actually occurs in applicationWillTerminate:, because you try to archive dataset, which is probably nil, and it's probably not allowed to archive nil.
With ARC you should use strong and weak instead of retain and assign.

NSString out of scope

I used the codes below to set a NSString
#import <Foundation/Foundation.h>
#interface AppController : NSObject
{
NSString *myString;
}
#property (nonatomic, retain) NSString *myString;
#end
#import "AppController.h"
#implementation AppController
#synthesize myString;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSString *zs0= [[NSString alloc] initWithFormat: #"abc"];
myString =[zs0 retain];
[zs0 release];//breakpoint
}
- (void)dealloc {
[myString release];
[super dealloc];
}
#end
when I check the value of myString at the breakpoint
it always said 'out of scope'
Welcome any comment
You don't need the temp variable zs0 - just assign it to the property
You don't need initWithFormat since you're not formatting.
You don't need to alloc the string - if you call [NSString stringWithString] it will autorelease it and then when you assign it to a (retain) property, it will retain it.
You're over retaining. You alloc the string which gives it a retain count of 1, then you retain it which gives it 2, then you assign it to a retained property which retains it again.
One simple way is:
self.myString = [NSString stringWithString:#"abc"];
That will create a string that's autoreleased (not created with alloc, copy by convention) and then the property will retain it.
Why are you using initWithFormat if you aren't using a format?Next, why even allocate zs0 if you aren't going to use it? Just set myString to what you want it to be.
Thus, your code should look like this:
myString = [[NSString alloc] initWithString: #"abc"];
Try that and everything should work.

Resources