为什么我不能通过setter初始化一个类?

Rob*_*Rob 1 getter setter objective-c

如果我有一个名为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
Run Code Online (Sandbox Code Playgroud)

我在View Controller中合成了一个setter和getter:

#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
Run Code Online (Sandbox Code Playgroud)

它在[self setFrontLeft:[[Tires alloc] init]]回来后死亡.它编译得很好,当我运行调试器时它实际上一直通过Tires上的init方法,但一旦它返回它就会死掉,视图永远不会出现.但是,如果我将viewDidLoad方法更改为:

- (void)viewDidLoad {
     [super viewDidLoad];
     frontLeft = [[Tires alloc] init];
}
Run Code Online (Sandbox Code Playgroud)

它工作得很好.我可以直接抛弃setter并直接访问frontLeft变量,但我的印象是我应该尽可能多地使用setter和getter,从逻辑上讲,似乎setFrontLeft方法应该可行.

这引出了我的同事在这些方面不断提出的另一个问题(我们都是Objective-C的新手); 如果你和那些setter和getter在同一个类中,为什么要使用setter和getter.

小智 7

您已将frontLeft声明为"复制"属性:

@property (nonatomic,copy) Tires *frontLeft, *frontRight, *backleft, *backRight;
Run Code Online (Sandbox Code Playgroud)

分配给此属性时,将通过调用对象的copy方法来创建副本.这仅适用于支持NSCopying协议的对象(即实现copyWithZone:方法).由于您的Tires类没有实现此方法,因此会出现异常.

您可能希望将其更改为"保留"属性:

@property (nonatomic,retain) Tires *frontLeft, *frontRight, *backleft, *backRight;
Run Code Online (Sandbox Code Playgroud)

有关属性声明的更多信息,请参阅有关已声明属性的Objective C文档.