5

Ivars を宣言せずにスーパークラスで a を宣言@propertyし、それをサブクラス化し、サブクラスでスーパークラス ivar() を使用して getter を実装しようとすると_propertyName、xcode は を示すエラーを呼び出しますUse of undeclared identifier '_propertyName'

ベスト プログラミング プラクティスに準拠するソリューションは何ですか?

@synthesize propertyName = _propertyName@implementationサブクラスの中にいるべきですか、それとも

@interface SuperClass : AnotherClass
{
    Type *_propertyName;
}

@property Type *propertyName;

@end

編集:
プロパティのアクセサーメソッドの自動「合成」と、コンパイラーによる「アンダーバー ivar」の作成を理解しています。 ivar は、インターフェイスまたは実装セクションでの ivar の宣言または宣言 なし
で、の実装からアクセスできます。SuperClass@synthesize

私のケースのさらなる説明: 免責事項: アルフィー・ハンセンから盗まれたコードのブロックの内容

@interface SuperViewController : UIViewController
@property (nonatomic, strong) UITableView * tableView; // ivar _tableView is automatically @synthesized
@end

#import "SuperViewController.h"

@interface SubViewController : SuperViewController
// Empty
@end

@implementation SubViewController

- (void)viewDidLoad
{
    NSLog(@"tableView: %@", self.tableView); // this is perfectly OK
}

// ************* This causes problem **************
- (UITableView *) tableView {
    if (!_tableView) {    // Xcode error: Use of undeclared identifier '_propertyName'
        _tableView = [[SubclassOfUITableView alloc] init];
    }
    return _tableView;
}
// ************************************************


@end
4

5 に答える 5

7

スーパークラスとサブクラスの両方で ivar を使用する場合は、スーパークラスのインターフェイスで宣言する必要があります。これは、両方の実装に含まれる唯一のファイルだからです。そうしないと、スーパークラスの実装に何があるかを推測しようとしているだけで、xcode はゲームをプレイしません。

上記は、そのivarを使用するプロパティがあるかどうかに関係なく当てはまります。

スーパークラスにプロパティがあり、サブクラスの実装に書き込む場合:

@synthesize propertyName = _propertyName

そのプロパティの実装がスーパークラスにあったものは何でも捨てて、_propertyname という名前の ivar で作業して、xcode によって生成された標準のセッターとゲッターが必要だと言っているだけです。スーパークラスも同じように機能するかもしれませんし、そうでないかもしれません。

于 2013-08-06T17:01:11.943 に答える
0

これで問題なく動作するはずです。self.tableView_tableViewから両方にアクセスできる必要がありますSubViewController

@interface SuperViewController : UIViewController
@property (nonatomic, strong) UITableView * tableView; // ivar _tableView is automatically @synthesized
@end

#import "SuperViewController.h"

@interface SubViewController : SuperViewController
// Empty
@end

@implementation SubViewController

- (void)viewDidLoad
{
    NSLog(@"tableView: %@", self.tableView);
}

@end

編集: さて、あなたの質問がよく理解できました。この質問をチェックしてください。重複しているようで、あなたの質問に答えているようです。つまり、インスタンス変数を明示的に定義する必要があるようです。

于 2013-08-06T14:59:49.973 に答える
0

によって作成された Ivars@synthesize@private. @synthesize(これは、明示的なステートメントと自動合成の両方に当てはまります。)

あなたのクラスSuperViewControllerには ivar_tableViewがあり@privateますが、サブクラスはそれを使用できません。サブクラスが使用できる ivar が必要な場合は、その ivar を明示的に宣言し、@private. (@synthesize tableView=_tableViewプロパティが宣言されたivarを使用するように使用することもできます。)

于 2013-08-06T19:32:44.203 に答える