1

Tires というカスタム クラスがある場合:

#import <Foundation/Foundation.h>

@interface Tires : NSObject {
@private
     NSString *brand;
     int size;
}

@property (nonatomic,copy) NSString *brand;
@property int size;

- (id)init;
- (void)dealloc;

@end
=============================================

#import "Tires.h"

@implementation Tires

@synthesize brand, size;

- (id)init {
     if (self = [super init]) {
          [self setBrand:[[NSString alloc] initWithString:@""]];
          [self setSize:0];
     }
     return self;
}

- (void)dealloc {
     [super dealloc];
     [brand release];
}

@end

そして、View Controller でセッターとゲッターを合成します。

#import <UIKit/UIKit.h>
#import "Tires.h"

@interface testViewController : UIViewController {
     Tires *frontLeft, *frontRight, *backleft, *backRight;
}

@property (nonatomic,copy) Tires *frontLeft, *frontRight, *backleft, *backRight;

@end

====================================

#import "testViewController.h"

@implementation testViewController

@synthesize frontLeft, frontRight, backleft, backRight;

- (void)viewDidLoad {
     [super viewDidLoad];
     [self setFrontLeft:[[Tires alloc] init]];
}
- (void)dealloc {
    [super dealloc];
}

@end

[self setFrontLeft :[[Tires alloc] init]]が戻ってきた後に終了します。それは問題なくコンパイルされ、デバッガーを実行すると、実際にはTiresのinitメソッドを完全に通過しますが、戻ってくると、ただ死んでビューが表示されません。ただし、viewDidLoadメソッドを次のように変更すると:

- (void)viewDidLoad {
     [super viewDidLoad];
     frontLeft = [[Tires alloc] init];
}

それはうまく動作します。セッターを捨てて直接frontLeft変数にアクセスすることもできましたが、可能な限りセッターとゲッターを使用する必要があるという印象を受けました。論理的にはsetFrontLeftメソッドが機能するようです。

これは、私の同僚がこれらの点で尋ね続けている追加の質問をもたらします (私たちは皆、Objective-C を初めて使用します)。それらのセッターとゲッターと同じクラスにいる場合、なぜセッターとゲッターを使用するのですか。

4

2 に答える 2

7

frontLeftを「コピー」プロパティとして宣言しました。

@property (nonatomic,copy) Tires *frontLeft, *frontRight, *backleft, *backRight;

このプロパティに割り当てると、オブジェクトのcopyメソッドを呼び出してコピーが作成されます。これは、NSCopyingプロトコルをサポートするオブジェクト(つまり、copyWithZone:メソッドを実装するオブジェクト)に対してのみ機能します。Tiresクラスはこのメソッドを実装していないため、例外が発生します。

おそらく、これを「保持」プロパティに変更する必要があります。

@property (nonatomic,retain) Tires *frontLeft, *frontRight, *backleft, *backRight;

プロパティ宣言の詳細については、宣言されたプロパティに関するObjectiveCのドキュメントを参照してください。

于 2010-05-02T22:08:47.123 に答える
1

私が見る1つの問題はここにあります:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setFrontLeft:[[Tires alloc] init]];
}

[Tires alloc] を呼び出すと、保持カウントが 1 のオブジェクトが返されます。次に、合成した set メソッドを使用して、保持カウントを 2 に増やします。オブジェクトが Tire オブジェクトで処理されると、次のようになります。保持カウントを 1 に戻しますが、タイヤの割り当てが解除されることはありません。私はあなたが使うべきだと思います:

[self setFrontLeft:[[[Tires alloc] init] autorelease]];
于 2010-05-02T21:19:06.460 に答える