Reputation: 9273
i have a problem passing a string to another UIViewController and then open this UIViewController, this is what i do:
.h
#import <UIKit/UIKit.h>
@interface BroswerViewController : UIViewController
@property (retain, nonatomic) IBOutlet UIWebView *myBrowserView;
@property (nonatomic, retain) NSString * myString;
@end
.m
@implementation BroswerViewController
@synthesize myBrowserView;
@synthesize myString;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
myString = [myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://mywebsite/%@",myString]];
NSLog(@"%@",url);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[myBrowserView loadRequest:request];
}
class where i call it:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.myBroserViewController) {
self.myBroserViewController = [[[BroswerViewController alloc] initWithNibName:@"BroswerViewController" bundle:nil] autorelease];
}
[self.myBroserViewController setMyString:[NSString stringWithString:[stringArray objectAtIndex:indexPath.row]]];
[self.navigationController pushViewController:self.myBroserViewController animated:YES];
}
ok, so i pass a string to the BrowseViewController class, and then open the browseviewcontroller class and open the url with the string i have passed, and the first time work always, then i return back and pass another string and open the view and the second time works random, and the third time never, and i always receive a EXC_BAD_ACCESS on the line
@synthesize myString;
i don't know what i wrong...
Upvotes: 0
Views: 152
Reputation: 11818
in my code i change the instance variable name within my synthesize.
Here is what your code could look like
@implementation BroswerViewController
@synthesize myBrowserViewh = _myBrowserViewh;
@synthesize myString = _myString;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
self.myString = [self.myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://mywebsite/%@",self.myString]];
NSLog(@"%@",url);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[myBrowserView loadRequest:request];
}
at that point you would be forced to use either
self.myString = @"";
or reference the instance variable via
_myString = @"";
this would let the compiler help you find bugs like this.
Upvotes: 0
Reputation: 16124
I would add a couple of pointers to @Phillip Mills answer.
-On your init you should set myString to nil. This ensures that if it is released before being set somewhere else, it won't crash. Including if you use the setter which performs a release on it (you can release a nil reference).
-On your dealloc, you should release myString (unless you are using ARC).
-When you set it in viewWillAppear, you either need to do:
self.myString = [self.myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
or
NSString *temp = myString;
[myString release];
myString = [[temp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] retain];
they both accomplish the same thing. Using self is easier though.
-Finally, I would use copy instead of retain unless you have a very specific reason to use retain. This ensures something else doesn't change it on you.
Upvotes: 1
Reputation: 44
Best practices tells us use copy instead of retain in cases like this. That's why:
myString = [myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
changes the initial string too and next time you call this for already escaped string. That's why you get such weird behavior :)
Solution - change
@property (nonatomic, retain) NSString * myString;
ON
@property (nonatomic, copy) NSString * myString;
Using
self.myString
will solve it too, but it's still not a good practice... if, for example, your method will look like this:
NSURLRequest *request = [NSURLRequest requestWithURL:[self prepareUrl:self.myString]];
you still can catch very weird and hardly debugable artifacts.
Upvotes: 0
Reputation: 31016
Use self.myString
rather than the plain variable when you reference it in viewWillAppear:
. You're not getting the effect of the retain attribute when you use the variable directly rather than property notation.
Upvotes: 3