objective-c - Objective C - 使用相同实例变量的两个合成属性?

标签 objective-c ios properties key-value-coding foundation

我有一个代表一些数据的类。
我从 JSON 格式的 Web 服务获取这些数据。
Web 服务不符合 Objective-C 命名约定。更具体地说,对象的所有属性都以大写字母开头,例如 Name .

我希望能够利用内置的 KVC,但仍然使用 Objective-C 命名约定构建我的对象。

因此,在我的公共(public)类声明中,我声明了一个属性:

@interface TVPage : NSObject
@property (nonatomic, copy) NSString *name;
@end

在我的 *.m 文件中,我声明了一个类别扩展以符合 Web 服务命名约定:
@interface TVPage ()
@property (nonatomic, copy , getter = name , setter = setName:) NSString *Name;
@end

在私有(private)属性中,我指定了我想要实际访问数据的 getter 和 setter。

我想要实现的只是另一种方法,称为 Name实际上会调用 name在幕后。 ( setName: 实际上适合 Namename )

我的问题是,当我合成这样的属性时:
@implementation TVPage
@synthesize name;
@synthesize Name;
@end

它会生成两个不同的实例变量,称为 Namename或者它是否足够聪明,可以理解不这样做并只创建一个名为 name 的?

我可以明确告诉编译器 - “不要为此属性生成 Ivar”吗?

谢谢!

编辑:

我为什么要这样做?

很多人问我到底想在这里实现什么。
好吧,在解析从 Web 服务返回的数据时,我想做的是让我的生活更轻松。

数据作为 JSON 字符串返回。这意味着当我解析它时,我可能会取回 NSDictionaries 来表示数据。

我想轻松地创建我设计用来保存这些数据的对象,因为将字典用作数据模型不方便、不安全或不可读。

现在,键值编码功能允许我直接从字典中使用 setValuesForKeysWithDictionary: 设置对象的属性。

但这只有在我的对象实际上具有与字典键同名的访问器方法时才有效。如果我的对象中有一个没有匹配属性的键,我会从 setValue:forUndefinedKey: 得到一个异常。 .

为了避免我想创建 Facade Interface这将符合来自服务器的属性名称所隐含的键值编码方法。同时,我希望该接口(interface)的实现将访问“常规”接口(interface)访问的相同数据。

最佳答案

正如我所说,编写一些测试代码,然后不要继续你正在做的任何事情。

@property (strong, nonatomic) NSString *name;
@property (nonatomic, copy , getter = name , setter = setName:) NSString *Name;

@synthesize两个都。为了看看会发生什么,我们将一些日志记录代码放入我们的 s/getter 中,就像这样。
- (void)setName:(NSString *)aName {
    NSLog(@"setter called");
    name = aName;
}

- (NSString *)name {
    NSLog(@"getter called");
    return name;
}

现在有一些测试的乐趣。
NSLog(@"setValue:forKey: with Key name");
[self setValue:@"Name" forKey:@"name"];
NSLog(@"setValue:forKey: with Key Name");
[self setValue:@"Name" forKey:@"Name"];

NSLog(@"valueForKey: with Key name");
NSLog(@"ptr: %p", [self valueForKey:@"name"]);
NSLog(@"valueForKey: with Key Name");
NSLog(@"ptr: %p", [self valueForKey:@"Name"]);

NSLog(@"\n");

NSLog(@"calling setter via dot-notation for name");
self.name = @"foo";
NSLog(@"calling setter via dot-notation for Name");
self.Name = @"foo";

NSLog(@"calling getter via dot-notation for name");
NSLog(@"ptr: %p", self.name);
NSLog(@"calling getter via dot-notation for Name");
NSLog(@"ptr: %p", self.Name);

让我们运行它。等等。
[4115:f803] setValue:forKey: with Key name
[4115:f803] setter called
[4115:f803] setValue:forKey: with Key Name
[4115:f803] setter called
[4115:f803] valueForKey: with Key name
[4115:f803] getter called
[4115:f803] ptr: 0x36d8
[4115:f803] valueForKey: with Key Name          <-----
[4115:f803] ptr: 0x0                            <-----
[4115:f803] 
[4115:f803] calling setter via dot-notation for name
[4115:f803] setter called
[4115:f803] calling setter via dot-notation for Name
[4115:f803] setter called
[4115:f803] calling getter via dot-notation for name
[4115:f803] getter called
[4115:f803] ptr: 0x3758
[4115:f803] calling getter via dot-notation for Name
[4115:f803] getter called
[4115:f803] ptr: 0x3758

你看?自定义 setter/getter name不要求 valueForKey:@"Name" .但是调用了自定义 setter 。但可能只是因为您不能将大写字母大写。

希望大家不要盲目使用setValuesForKeysWithDictionary:有一堆值。无论如何,您都必须验证这些键,因为您不想为像 self 这样的键调用该方法。 , description等等。因此,当您验证 key 时,只需“取消大写” key 的名称即可。
恕我直言,删除大写字母是一种更清洁的方法,因为它不会像那些奇怪的影子变量那样发生一半的访问器方法失败。

关于objective-c - Objective C - 使用相同实例变量的两个合成属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9964578/

相关文章:

SwiftyJSON 如何正确访问变量?

iphone - iOS 7 上的 UITextView 的 inputView

xcode - 放大和缩小 UIView

java - Quartz 属性不会触发 Quartz Job

ios - SceneKit - 向场景添加新的 SCNNode 会导致严重滞后

ios - 解析错误预期标识符或 '('

java - 没有 setter 的 JPA 2.0 持久属性

ios - 将 makeObjectsPerformSelector 与对象一起使用

objective-c - xcode 中的 c 函数声明/用在调试和发布中表现不同的东西替换 NSLog

objective-c - 警告 "Use of GNU statement expression extension"