【问题标题】:When declaring class properties/variables, can you just declare it via @property?声明类属性/变量时,可以只通过@property 声明吗?
【发布时间】:2011-04-03 18:18:43
【问题描述】:

我注意到一些生成的类只通过@property 声明类属性/变量,并没有将它们包含在@interface 中,例如:

@interface AddItemViewController : UITableViewController {

}

@property (nonatomic, retain) UITextField *itemName;

我只是好奇这是一种可以接受的方式,还是出于不同的原因?

我通常这样做:

@interface AddItemViewController : UITableViewController {
  UITextField *itemName;
}

@property (nonatomic, retain) UITextField *itemName;

我先在@interface中声明它,然后为它添加@property...

* 更新 *

我只是想稍微更新一下,因为我还不是 100% 清楚。

我一直认为要声明一个@property,首先需要在@interface中声明它,然后我看到了这个:

@interface mInventoryAppDelegate : NSObject <UIApplicationDelegate> {

}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@end

所有这些@property 声明都只声明为@properties,而不是在@interface 中。

例如,如果我说NSString *myString - 我可以在@interface 中声明它而不是@property 并且仍然可以访问它没有问题,但不会创建getter 和setter。我也可以在两者中声明它。但是,如果我只是将其声明为@property 会怎样:

@interface AddItemViewController : UITableViewController {

}

@property (nonatomic, retain) NSString *myString;

注意我没有在 @interface { } 之间添加它 - 它有什么不同。

很抱歉重复一遍,但我只是想改写一下,以便我能得到一个对我更有意义的答案。

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    使用 iPhone 使用的“现代”运行时,编译器可以为您创建实例变量。只需使用:

    @synthesize itemName;
    

    或者如果你喜欢...

    @synthesize itemName=_itemName;
    

    ...在您的实现中。然后编译器将创建 ivar 'itemName' 或 '_itemName'。

    这当然是针对属性是一个特定实例变量的简单 getter/setter 的情况。

    编辑:NVM,根据@bbum,我认为的“32 位”模拟实际上是旧的模拟器,它的行为不像新的运行时。较新的模拟器仍然是 32 位的,并且支持这种行为。请参阅下面的评论。

    更新

    针对您更新的问题:

    类的“接口”是@end 之前的所有内容。我认为您所说的“接口”实际上只是 {} 中的实例变量。 {} 之间的内容是您的类的实例变量。整个 @interface 包括这些实例变量以及 {} 和 @end 之间的方法和 @property 声明。

    所以我认为您真正要问的是您的@interface 中是否有一个@property,并且@property 只是一个简单的getter/setter 对,那么您是否还需要在其中声明一个“支持”实例变量您的@interface,在 {} 内。

    iPhone 的答案是否定的。编译器(两者)都可以为您创建该实例变量。

    我希望这能回答问题?

    【讨论】:

    • 但这并不能回答我是否应该/需要在@interface 中声明它,或者是否可以将其声明为@property。有什么区别?
    • 模拟器只有一个; 32位模拟器。它现在可以工作了,因为模拟器已更新为具有类似于 iPhone 上的运行时。没有64位模拟器。
    • 哦,谢谢,不知道。一直以为去年夏天的“固定”模拟器是 64 位的。
    • 太糟糕了,我忘记了现代运行时自动创建 ivars 的能力:-)
    • 无论如何,显式创建 ivars 有几个很好的理由:(1) 调试器不显示未明确支持的属性的值 (2) 在某些情况下没有 ivars 的属性隐藏超类 ivars(stackoverflow.com/questions/3957288/…;虽然这可能是 gcc-only)。
    【解决方案2】:

    这样做是完全可以接受的。但是,您需要自己实现 setter/getter 方法。这些不能使用@synthesize 语法创建。

    使用这种方法的一个原因可能是让属性基于比设置和获取值更复杂的东西。但是,对于您的示例中的简单 Nib 连接没有多大意义。

    【讨论】:

    • 所以@property@synthesize 不会在第一个示例中生成getter 和setter(我没有在@interface 中定义它)?
    • 这是不正确的。 @synthesize 适用于隐式 ivars。
    • @Seamus 你是绝对正确的(在现代运行时的情况下)
    猜你喜欢
    • 1970-01-01
    • 2016-03-27
    • 2012-03-10
    • 2023-03-26
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    相关资源
    最近更新 更多