2012-03-14 9 views
0

私はこの問題を4日間近く処理しています。NSObjectからUIViewControllerへのデータの送信

私は、私のコードでそれほど問題ではないと思うが、問題を引き起こしているアプリケーションの構造だと思う。

私は1つのNSObject(クラス)からViewControllerに配列を取得するためのプロトコルとデリゲートを実装しようとしています。

私のコードだけの違いは、私がARCがオンになっている顔であるこのtutorialからコピーしたラインによって、かなり多くの行があるので、(強い)に(、非アトミック保持)を交換しなければならなかったとのdealloc :)

使用していません

だから、それはまだviewcontrollerにデータを戻さないと言われています。 (非常に迷惑な)私は何十ものさまざまな組み合わせのソリューションを試してきました。これは私のアプリケーションの構造や、初期化された方法などに誤りがあり、私が今説明しようとしていると信じさせてくれました。

私のパーサクラスのデリゲートと呼ばれるviewdidloadメソッドをtableviewでロードすると、tableviewの最初のセルがロードされ、接続クラスが呼び出され、サーバーからデータをダウンロードするように指示されます。 私の接続クラスの中で、アップルライブラリのNSURLConnectionデリゲートをdelegateメソッドのconnectionDidFinishLoadingで使用しています。ダウンロードされたデータはパーサクラスに渡されます(ただし、これはオブジェクトが再び宣言されるために間違っていると思います。これは私の接続クラスからパーサークラスを呼び出す方法です。データは私のパーサクラスになると

parserClass *myparser = [[EngineResponses alloc] init]; 
[myparser ReciveResponse:receivedData]; 

は、それが解析されますし、私は私のViewControllerの間でデータを渡すためにしようと..しかし、その私が設定しているデリゲートメソッドにアクセスすることはありません。

これはうまくいけば、どこに間違っているのか分からないためです。 あなたはどう思いますか?

UPDATE:HERESに私のコード -

ViewController.h

#import "EngineResponses.h" //delegates & protocols 

interface SearchViewController : UITableViewController <PassParsedData> { 

//delegates to parser class 
    EngineResponses *engineResponses; 
//.. 

ViewController.m

#import "EngineResponses.h" 

//this is where I set up the delegate/protocol for the parser class 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

//.. 
engineResponses = [[EngineResponses alloc] init]; 
[engineResponses setMydelegate:self]; 
//.. 
} 

//this is where i set up and call the connection class 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
//.. 
if(indexPath.section == 0){   
    //.. 
    if (indexPath.row == 0){ 
    EngineRequests *engineRequests = [[EngineRequests alloc] init]; 
       [engineRequests initalizePacketVariables:0 startCode:@"myReg" activationCode:@"myAct" methodName:@"GetStuff"]; 
       //.. 
} 

#pragma - Reciver methods 

- (void)sendArray:(NSArray *)array 
{ 
    ICMfgFilterArray = array; 
    [self.tableView reloadData]; 
} 

EngineRequests.m

//connection delegates etc.. 
//then I pass the data from the connection delegates over to the parser class 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    EngineResponses *engineResponses = [[EngineResponses alloc] init]; 
    [engineResponses ReciveResponse:receivedData]; 
} 

EngineResponses.h

@protocol PassParsedData 
- (void)sendArray:(NSArray *)array; 
@end 

//.. 
id <PassParsedData> mydelegate; 
//.. 
@property (strong) id <PassParsedData> mydelegate; 

EngineResponses.m

- (void)parserDidEndDocument:(NSXMLParser *)parser 
{ 
//.. 
    [[self mydelegate]sendArray:filteredArray];  
} 
+0

コードの編集されたバージョンは、散文の説明よりも診断しやすいでしょう。 –

+0

um、あなたは '[myParser setDelegate:myViewController];'のようなことをしていますか?また、より良いソリューションを提案するには、実際にコードを参照する必要があります。 – ColdLogic

+0

大丈夫、私は自分のコードを更新しました..申し訳ありませんが、それは長い時間がかかりました、私は完全にすべてを持っていることを確認した..だから私はエラーが私は2つの場所にパーサーオブジェクトを割り当てていると思う...しかし、これが正しいか、それを解決する方法を確認してください。 –

答えて

1

オールライト。私はあなたの更新されたコードに基づいてそれをやり直します。それを簡単にするために、あなたのコードをコピーし、修正を行います。

ViewController.h

#import "EngineResponses.h" //delegates & protocols 

interface SearchViewController : UITableViewController <PassParsedData> { 

//delegates to parser class 
    EngineResponses *engineResponses; 

    EngineRequests *engineRequests; 
//.. 

説明: あなたはARCを使用しています。ポインタをローカルで定義した場合は、以前のように を保持しないでください。これはARCのためにできません。 を作成した直後に解放されます。オブジェクトへの参照を少なくとも1つは保持する必要があります。 ARCはAutomatic Reference Countingを意味することに注意してください。オブジェクトへの参照がない場合は、解放されます。 ここで定義されたengineRequestsオブジェクトを持つこの提案は、 一度に1つのリクエストのみを送信している間のみ機能します。複数のリクエスト(複数のセルまたは )をリクエストしている場合は、リクエストを使用している間に変更可能な配列または可変ディクショナリに移動してください。

ViewController.m

#import "EngineResponses.h" 

//this is where I set up the delegate/protocol for the parser class 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

//.. 
engineResponses = [[EngineResponses alloc] init]; 
[engineResponses setMydelegate:self]; 

engineRequests = [[EngineRequests alloc] init]; // Use instance variable instead of local variable 
[engineRequests setEnineResponses:engineResponses]; 

//.. 
} 

//this is where i set up and call the connection class 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
//.. 
if(indexPath.section == 0){   
    //.. 
    if (indexPath.row == 0){ 
    [engineRequests initalizePacketVariables:0 startCode:@"myReg" activationCode:@"myAct" methodName:@"GetStuff"]; 
       //.. 
} 

#pragma - Reciver methods 

- (void)sendArray:(NSArray *)array 
{ 
    ICMfgFilterArray = array; 
    [self.tableView reloadData]; 
} 

説明:engineRequetsは現在インスタンスvaraibleであり、局所的に再定義されるべきではありません。 インスタンス変数を非表示にする同じ名前の変数をローカルに定義できます。私は その場合はコンパイラの警告を得るが、それは動作し、おそらくあなたを混乱させると思う。 また、一度に複数のリクエストを使用すると、このソリューションは機能しません。

EngineRequests.h

EngineResponses *engineResponses; 

EngineRequests.m

@synthesize engineResponses; 

//connection delegates etc.. 
//then I pass the data from the connection delegates over to the parser class 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    //EngineResponses *engineResponses = [[EngineResponses alloc] init]; //This Object has already been created! 
    [engineResponses ReciveResponse:receivedData]; 
} 

説明:ここでも、EngineResponsesへの参照は、現在のインスタンス変数ではなく、ローカルに定義されたものです。オブジェクトは新しく作成されませんが、ビューコントローラーで作成されたそのオブジェクトを参照します。これはView Controllerオブジェクトを '知っている' EngineResponsesの1つで、解析されたデータを返すことができます。

EngineResponses.h

@protocol PassParsedData 
- (void)sendArray:(NSArray *)array; 
@end 

//.. 
id <PassParsedData> mydelegate; 
//.. 
@property (strong) id <PassParsedData> mydelegate; 

EngineResponses.m

- (void)parserDidEndDocument:(NSXMLParser *)parser 
{ 
//.. 
    [[self mydelegate]sendArray:filteredArray];  
} 

...それを試してみる:)

+0

大丈夫です。私は今、試して、私の結果を投稿します。 –

+0

残念ながら..私はあなたの答えに基づいて、ここで何をする必要があるのか​​よくわかりません。 –

+0

私は[engineRequests setMydelegate:self]を呼び出します。 cellForRowAtIndexPathからこのエラーが発生しました** Instanceメッセージの受信者タイプ 'EngineRequests'は、セクレーター 'setMyDelegate'を使ってメソッドを宣言しません** –

0

をnilのオブジェクトに対して、必ず確認してください。 nilオブジェクトにメッセージを送信すると何も起こらず、あなたのアプリは続行されます。私はあなたがローカルにすべての場所にローカルに割り当てているので、これが問題だと思います。なぜあなたはいくつかの計算と解析のためにこれらのクラスが数分以上必要ないように見えるので、受信メソッドを静的メソッドにするのはなぜですか?それでは、nilオブジェクトは重要な要素にはなりません。

+0

viewController内のconnectionDidFinisLoadingなどは、一度に1つの要求が「空中」にある場合に正常に動作します。個々のリクエストが多数のテーブルセルに対して送信される場合、C.Johnsのアプローチはずっと安全です。 –

関連する問題