【问题标题】:Why are some object members out of scope in Objective C为什么某些对象成员超出了 Objective C 的范围
【发布时间】:2010-12-04 16:40:20
【问题描述】:

我是从 Java 背景开始接触 Objective-C 的。我无法理解为什么以下代码会生成异常。

    
@interface Stopwatch : NSObject {
    NSDate *start;
    int    mode;
}
@property(nonatomic,assign) NSDate *start;
@property(nonatomic,assign) int mode;
@end

@implementation Stopwatch
@synthesize start, mode;
-(id) init{
    self = [super init];
    if(self){
        start = [NSDate date];
        mode = -1;
    }
    return self;
}
@end


@interface StopwatchController : NSObject {
    Stopwatch *stopwatch;
}
@property (nonatomic,assign) Stopwatch *stopwatch;

- (void) useStopwatch:(Stopwatch*)aStopwatch;
- (void) updateStopwatch;
@end

@implementation StopwatchController
@synthesize stopwatch;

- (void) useStopwatch:(Stopwatch*)aStopwatch{
    stopwatch = aStopwatch;
}

- (void) updateStopwatch{
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
    [dateFormat setTimeStyle:NSDateFormatterMediumStyle];
    [dateFormat setDateStyle:NSDateFormatterMediumStyle];
    NSString *string = [dateFormat stringFromDate:stopwatch.start];
    NSLog(@"%@",string);
}
@end

所以当以下代码运行时,我看到 stopwatch.start 超出范围,但不是秒表?


Stopwatch *sw = [[Stopwatch alloc]init];
StopwatchControlelr *swc = [[StopwatchController alloc]init];
[swc useStopwatch:sw];
[swc updateStopwatch];

【问题讨论】:

    标签: iphone objective-c memory-management


    【解决方案1】:

    在你的初始化中

    start = [NSDate date];
    

    不使用 start 属性——它使用 start 实例变量。这意味着永远不会调用保留。 [NSDate date] 返回一个将自动释放的对象。

    我的建议是使用

    self.start = [NSDate date];
    

    这使用了属性。在您的情况下,我还将声明此属性retain,而不是assign。如果你保留它assign,你需要调用retain。所以使用assign,也可以这样做

    [self.start retain];
    

    确保你做对的一种方法是声明这样的字段

    NSDate * _start;
    

    这样的属性

    @property (retain, nonatomic) NSDate * start;
    

    然后像这样合成

    @synthesize start = _start.
    

    然后您知道何时使用实例变量(绕过任何集合调用、自动保留等)或属性。

    如果你这样做了,那么这将无法编译

       start = [NSDate date];
    

    你要么需要改变这个

       self.start = [NSDate date]; // use property
    

    或者这个

       _start = [NSDate date]; // use instance variable
    

    【讨论】:

      【解决方案2】:

      [NSDate date] 为您提供一个自动释放的实例,当相关的自动释放池耗尽时,该实例将被释放。您必须保留它才能获得所有权,请参阅Cocoa Memory Management 上的文档。

      【讨论】:

        猜你喜欢
        • 2012-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-13
        • 1970-01-01
        • 2016-03-17
        • 2011-04-29
        相关资源
        最近更新 更多