从另一个类设置NSString属性时出错

时间:2012-05-12 00:31:05

标签: iphone ios uiviewcontroller

我在将字符串传递给另一个UIViewController然后打开这个UIViewController时遇到了问题,这就是我所做的:

·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];

}

我称之为的课程:

- (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];
}

好吧,所以我将一个字符串传递给BrowseViewController类,然后打开browseviewcontroller类并使用我传递的字符串打开url,并且第一次总是工作,然后我返回并传递另一个字符串并打开查看和第二次随机工作,第三次永远不会,我总是在线上收到EXC_BAD_ACCESS

@synthesize myString;

我不知道我错了什么......

4 个答案:

答案 0 :(得分:3)

self.myString中引用它时,使用viewWillAppear:而不是普通变量。当您直接使用变量而不是属性表示法时,您没有获得retain属性的效果。

答案 1 :(得分:1)

我会在@Phillip Mills回答中添加几个指针。

- 在初始化时,你应该将myString设置为nil。这确保了如果在被设置到其他地方之前释放它,它将不会崩溃。包括你是否使用在其上执行发布的setter(你可以发布一个nil引用)。

- 在你的dealloc上,你应该释放myString(除非你使用ARC)。

- 在viewWillAppear中设置它时,您需要执行以下操作:

self.myString = [self.myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSString *temp = myString;
[myString release];
myString = [[temp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] retain];
他们都完成了同样的事情。使用self更容易。

- 最后,我会使用copy而不是retain,除非你有一个非常具体的理由使用retain。这可以确保其他东西不会改变它。

答案 2 :(得分:0)

最佳做法告诉我们在这种情况下使用copy而不是retain。 这就是原因:

myString = [myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

也会更改初始字符串,下次为已经转义的字符串调用此字符串。这就是为什么你会得到如此奇怪的行为:)。

解决方案 - 更改

@property (nonatomic, retain) NSString * myString;

@property (nonatomic, copy) NSString * myString;

使用

  

self.myString

也会解决它,但它仍然不是一个好习惯...例如,如果你的方法看起来像这样:

NSURLRequest *request = [NSURLRequest requestWithURL:[self prepareUrl:self.myString]];

你仍然可以捕获非常奇怪且难以调试的工件。

答案 3 :(得分:0)

在我的代码中,我更改了我的合成中的实例变量名称。

以下是您的代码的样子

@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];

}

此时你将被迫使用

self.myString = @"";

或通过

引用实例变量
_myString = @"";

这会让编译器帮你找到这样的bug。