0

文字列を別の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 を開きます。 2 回目はランダムに動作し、3 回目はまったく動作せず、回線で常に EXC_BAD_ACCESS を受け取ります

@synthesize myString;

何を間違えたのかわからない…

4

4 に答える 4

3

self.myStringで参照する場合は、単純な変数ではなく使用してくださいviewWillAppear:。プロパティ表記ではなく変数を直接使用すると、retain 属性の効果が得られません。

于 2012-05-12T00:42:02.017 に答える
1

@Phillip Millsの回答にいくつかのポインタを追加します。

-init では、myString を nil に設定する必要があります。これにより、他の場所に設定される前に解放された場合でも、クラッシュしないことが保証されます。リリースを実行するセッターを使用する場合も含みます(nil参照をリリースできます)。

-dealloc では、myString を解放する必要があります (ARC を使用していない場合)。

-viewWillAppear で設定する場合は、次のいずれかを行う必要があります。

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

また

NSString *temp = myString;
[myString release];
myString = [[temp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] retain];

どちらも同じことを達成します。ただし、 self を使用する方が簡単です。

- 最後に、retain を使用する特別な理由がない限り、retain の代わりに copy を使用します。これにより、他の何かがあなたにそれを変更しないことが保証されます.

于 2012-05-12T01:01:19.977 に答える
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 = @"";

これにより、コンパイラはこのようなバグを見つけるのに役立ちます。

于 2012-05-12T02:11:16.877 に答える
0

ベスト プラクティスでは、このような場合に保持ではなくコピーを使用するように指示しています。それが理由です:

myString = [myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

最初の文字列も変更し、次回はすでにエスケープされた文字列に対してこれを呼び出します。そのため、このような奇妙な動作が発生します:)

解決策 - 変更

@property (nonatomic, retain) NSString * myString;

オン

@property (nonatomic, copy) NSString * myString;

使用する

self.myString

それも解決しますが、それでも良い習慣ではありません...たとえば、メソッドが次のようになる場合:

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

非常に奇妙でほとんどデバッグできないアーティファクトをまだキャッチできます。

于 2012-05-12T00:58:22.600 に答える