2011-07-21 9 views
5

注:自動参照カウント(ARC)が有効なiOSを使用しています。私はARCがなぜこれが働いていないのと関係があるかもしれないと思うのですが、これはGoogleによって見つかった例に基づいて設定されています。iOS上でカスタム@プロトコルが動作しない

ユーザーがUITableViewから選択したファイル名をデリゲートに通知するプロトコルを作成しようとしています。

FileListViewController.h

@protocol FileListDelegate <NSObject> 
- (void)didSelectFileName:(NSString *)fileName; 

@end 

@interface FileListViewController : UITableViewController 
{ 
    @private 
     NSArray *fileList; 
     id <FileListDelegate> delegate; 
} 
@property (nonatomic, retain) NSArray *fileList; 
@property (nonatomic, assign) id <FileListDelegate> delegate; 

@end 

FileListViewController.m

#import "FileListViewController.h" 

@implementation FileListViewController 

@synthesize fileList; 
@synthesize delegate; 

これは「FileListViewController.mある

@synthesize delegate; 

行でエラー与える:エラー:自動参照カウントを問題:unsafe_unretainedプロパティ 'delegate'の既存のivar 'delegate'は、 __unsafe_unretained "

私がFileListViewController.hを入れて__weakと(weak)を入れた場合、それが実行されます。

@protocol FileListDelegate <NSObject> 
- (void)didSelectFileName:(NSString *)fileName; 

@end 

@interface FileListViewController : UITableViewController 
{ 
    @private 
     NSArray *fileList; 
     __weak id <FileListDelegate> delegate; 
} 
@property (nonatomic, retain) NSArray *fileList; 
@property (weak) id <FileListDelegate> delegate; 

@end 

しかし、私がデリゲートを設定しようとすると、アプリケーションがクラッシュします。 'ImportViewController'というビューは、 'FileListViewController'からビューを作成し、デリゲート自体を(ImportViewController)に設定して、 'didSelectFileName'というカスタムプロトコルを実装できます。私が得るエラーは次のとおりです。キャッチされない例外により 'NSInvalidArgumentException'、理由にアプリを終了

*: - 私が実行しているコードである

を '[ImportViewController setDelegate:]未認識セレクタインスタンス0x6c7d430に送ら';

ImportViewController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    FileListViewController *fileListViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"filelist"]; 

    [fileListViewController setDelegate:self]; 
    [self.navigationController pushViewController:fileListViewController animated:YES]; 

} 

私の質問は以下のとおりです。

  • はなぜ入れない(弱い)とで__weakそれを動作させますか?私はそれがなぜグーグルで見つかったので、 がなぜ機能するのか理解していないし、 の説明がなかった。
  • '[fileListViewController setDelegate:self];を使用して代理人を設定できないのはなぜですか? ? コンパイラは 'デリゲート'が存在しないようです。

    FileListViewController *fileListViewController = 
        [self.storyboard instantiateViewControllerWithIdentifier:@"filelist"]; 
    

    あなたがFileListViewControllerオブジェクトを取得できませんでした:

+0

これを解決しましたか? –

答えて

4

しているようです。

-[ImportViewController setDelegate:]: unrecognized selector sent to instance 0x6c7d430

、なぜあなたのアプリケーションがクラッシュしている:それは言うメッセージを見てください。デリゲートの割り当てを解除する代わりに、retainプロパティを定義してみてください。デリゲートが他の場所から割り当て解除された場合、アプリケーションはクラッシュしません。

+0

ありがとうございます。 instantiateViewControllerWithIdentifier:@ "filelist"は実際に間違ったコントローラを返していました。 – zio

1

私はこの同じ問題を突き抜け、最終的にARCのドキュメントを掘り下げました。多分私はiOSの5は、これは良いですと、あなたのデリゲートを保持すべきではないのベストプラクティスを変更したことはないと思う私の読書に基づいて、user756245の答えから、上記の引用を明確にするために

Also try to define a retain property, instead of just assign, in case the delegate is deallocated elsewhere, your app won't crash.

リークする方法。私は__weakと(弱い)トークンは、デリゲートのコードを生成することを正しく扱うことができるようにするためのコンパイラの注釈だと思います。

13

ARC ivarsのデフォルトはstrongです。だから、エラー

Automatic Reference Counting Issue: Existing ivar 'delegate' for unsafe_unretained property 'delegate' must be __unsafe_unretained" 

あなたは根本的IVARが違法である__strong所有権を持っている__unsafe_unretained(割り当て)所有権、とプロパティを宣言したことを語っています。このエラーを回避するには、3つのオプションがあります。

  1. ivarを省略します。合成されたプロパティのためにivarを宣言する必要はありません。 ivarはあなたの所有物と一致する所有権で暗黙のうちに宣言されます。あなたが持っているので、私はIVAR宣言を省略したい、個人的に@property (weak) id <FileListDelegate> delegate;

__unsafe_unretained id <FileListDelegate> delegate;

  • はIVARの暗黙の__strongの所有権に一致するようにプロパティを定義します。
  • あなた(割り当て)プロパティの宣言に一致するようにIVARを定義します所有権セマンティクスをプロパティ宣言の1つの場所で使用します。

  • 関連する問題