Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 子类属性_Objective C_Properties_Subclass - Fatal编程技术网

Objective c 子类属性

Objective c 子类属性,objective-c,properties,subclass,Objective C,Properties,Subclass,我想抽象地做以下几点: // .h @interface SomeObject : NSObject @property (readonly) NSArray myProperty; @end // .m @interface SomeObject () @property (readwrite) NSMutableArray myProperty; @end @implementation SomeObject @end 根据本节,允许使用readwrite覆盖只读属性。不起作用的是对属

我想抽象地做以下几点:

// .h
@interface SomeObject : NSObject
@property (readonly) NSArray myProperty;
@end

// .m
@interface SomeObject ()
@property (readwrite) NSMutableArray myProperty;
@end

@implementation SomeObject
@end
根据本节,允许使用readwrite覆盖只读属性。不起作用的是对属性类型使用子类。我使用NSMutableArray作为示例,但它可以是任何其他类/子类的组合

但根据继承规则,它应该是可以的。readonly只生成getter,它还可以返回一个子类对象

当您需要某个属性的子类类型供内部使用时,如何处理这种情况

下面是一个丑陋的方式,但我想避免,因为这意味着我不能使用自我。访问子类方法时的getter和setter

// .h
@interface SomeObject : NSObject
@property (readonly) NSArray myProperty;
@end

// .m
@implementation SomeObject {
    NSMutableArray _myProperty;
}
@synthesize myProperty = _myProperty;
@end
当您需要某个类的子类类型时,如何处理这种情况 内部使用的财产

属性明确不供内部使用,它们是公共接口的成员

如果需要内部值,请定义成员字段并重写属性的setter以设置内部值

当您需要某个类的子类类型时,如何处理这种情况 内部使用的财产

属性明确不供内部使用,它们是公共接口的成员

如果需要内部值,请定义成员字段并重写属性的setter以设置内部值。

根据编辑进行编辑:编辑后的特定情况是一种特殊和常见的情况,如果可以同时使用这两种情况,则需要仔细考虑

这是一个特殊的原因,因为子类是公开类的可变形式。调用者可能期望它在收到后不会改变。但是如果你把你的内部对象交回来,那么它可能会变异。您有几个选择:

返回一个不可变的副本。这通常是小型集合的最佳解决方案。这当然是最简单的。但是,如果访问器可能经常被调用,并且集合很大,那么它可能会非常昂贵

使您的内部属性不可变。如果对属性的请求比对属性的更改更为常见,则在对象使用arrayByAddingObject:、SubrayWithRange:等进行变异时,可以更高效地重新创建对象

警告调用方返回的对象可能会更改。。。。啊。。。我曾经在一个需要表演的地方这样做过,但这相当危险

我从来没有这样做过,但是你也可以用这种方式创建你自己的副本:直接返回可变版本,并标记一个标志它现在是脏的。当内部需要变异时,制作一个可变副本并将其存储在您的属性中,放弃旧集合。这似乎很复杂,但在某些情况下可能很有用,特别是当读和写操作倾向于在大量读操作之后单独聚集大量写操作时

基于NSObject与NSString的旧答案:

我假设您在这里的目标是使myProperty成为某种不透明类型,而不是泄露它是NSString的事实?也许你以后可以改变主意,看看它是如何实现的?有几个选择。最简单的方法是将其定义为id类型,然后在内部将其视为字符串。身份证可以是任何东西。它通常优于NSObject*

如果您希望在内部实现更多类型安全性,则可以创建另一个名称为NSString类型的私有属性,并将其返回给myProperty,如下所示:

某物 SomeObject.m 如果隐藏对您来说非常重要,那么可以使用的另一种隐藏技术是子类。例如:

某物 SomeObject.m 由于调用方没有MyOpaque的@interface定义,因此在没有编译器警告的情况下无法向其发送消息。

根据您的编辑进行编辑:编辑后的特定情况是一种特殊和常见的情况,如果可以同时使用这两种情况,则需要仔细考虑

这是一个特殊的原因,因为子类是公开类的可变形式。调用者可能期望它在收到后不会改变。但是如果你把你的内部对象交回来,那么它可能会变异。您有几个选择:

返回一个不可变的副本。这通常是小型集合的最佳解决方案。这当然是最简单的。但是,如果访问器可能经常被调用,并且集合很大,那么它可能会非常昂贵

使您的内部属性不可变。如果对属性的请求比对属性的更改更为常见,则在对象使用arrayByAddingObject:、SubrayWithRange:等进行变异时,可以更高效地重新创建对象

警告调用方返回的对象可能会更改。。。。啊。。。我曾经在一个需要表演的地方这样做过,但这相当危险

我从来没有这样做过,但你也可以用这种方式创建你自己的副本:returnt 他直接修改了这个版本,并标记了一个标志,表明它现在是脏的。当内部需要变异时,制作一个可变副本并将其存储在您的属性中,放弃旧集合。这似乎很复杂,但在某些情况下可能很有用,特别是当读和写操作倾向于在大量读操作之后单独聚集大量写操作时

基于NSObject与NSString的旧答案:

我假设您在这里的目标是使myProperty成为某种不透明类型,而不是泄露它是NSString的事实?也许你以后可以改变主意,看看它是如何实现的?有几个选择。最简单的方法是将其定义为id类型,然后在内部将其视为字符串。身份证可以是任何东西。它通常优于NSObject*

如果您希望在内部实现更多类型安全性,则可以创建另一个名称为NSString类型的私有属性,并将其返回给myProperty,如下所示:

某物 SomeObject.m 如果隐藏对您来说非常重要,那么可以使用的另一种隐藏技术是子类。例如:

某物 SomeObject.m
由于调用方没有MyOpaque的@interface定义,因此在没有编译器警告的情况下,调用方无法向其发送消息。

您所说的属性明确不供内部使用是什么意思?属性通常供内部使用。将它们放在私有类扩展中是很常见的。它们只有放在公共接口中才是公共的。这不是必须的。我们很多人,包括苹果公司,都非常普遍和强烈地建议使用私有财产。除了在init、dealloc和自定义访问器内部之外,您不应该直接访问IVAR。@stackmonster:您不需要私有状态的访问器的想法很奇怪。访问器处理的不仅仅是设置一个变量——它们还确保一致的内存管理并启用KVO,通常只是提高代码的模块性。早在引入声明属性之前,我就为私有状态使用了访问器,我知道很多其他人也这么做了。在con/destructor和accessor之外使用原始ivar访问的唯一逻辑原因是,如果您已经分析并发现访问器太慢了,否则访问器纯粹是win。我也一直使用private@properties。很长一段时间以来,我再也不用ivars了。苹果公司也这么做了,并建议这样做。而且它更好,因为它甚至在内部调用setter来实施良好的内存管理@属性从未被简化为用于公共接口。有关简单示例,请参见。PS:就我个人而言,我甚至将我的IBOutlet和IBAction放在.m文件中,以避免它们在我的公共API中被公开。事实上,除了公开公开状态之外,属性不存在,而且如果发明它们的人不同意你的意见也没关系?你以一种有趣的方式看待世界。很明显,你知道为什么他们把属性做得比他们好。你说的属性明确不供内部使用是什么意思?属性通常供内部使用。将它们放在私有类扩展中是很常见的。它们只有放在公共接口中才是公共的。这不是必须的。我们很多人,包括苹果公司,都非常普遍和强烈地建议使用私有财产。除了在init、dealloc和自定义访问器内部之外,您不应该直接访问IVAR。@stackmonster:您不需要私有状态的访问器的想法很奇怪。访问器处理的不仅仅是设置一个变量——它们还确保一致的内存管理并启用KVO,通常只是提高代码的模块性。早在引入声明属性之前,我就为私有状态使用了访问器,我知道很多其他人也这么做了。在con/destructor和accessor之外使用原始ivar访问的唯一逻辑原因是,如果您已经分析并发现访问器太慢了,否则访问器纯粹是win。我也一直使用private@properties。很长一段时间以来,我再也不用ivars了。苹果公司也这么做了,并建议这样做。而且它更好,因为它甚至在内部调用setter来实施良好的内存管理@属性从未被简化为用于公共接口。有关简单示例,请参见。PS:就我个人而言,我甚至将我的IBOutlet和IBAction放在.m文件中,以避免它们在我的公共API中被公开。事实上,除了公开公开状态之外,属性不存在,而且如果发明它们的人不同意你的意见也没关系?你以一种有趣的方式看待世界。很明显,你知道为什么他们的房产比他们做得更好。就我而言,拥有另一个名字变体的私有房产将是唯一有趣的。调用者应该能够根据公开的类型发送消息,但不能针对子类型。我更新了我的问题以更好地反映这一点。我们正在利用你
r目前是第三种方式,因为我们有一个经常变化的大数组。但是回到属性,您将如何以这种方式在内部使用属性?你认为用另一个名字命名的私有属性是最好的选择吗?顺便说一句,可变类作为非可换类的子类已经被证明是非常实用的,这让我很困惑。它实际上没有遵循继承规则。子类必须遵循与其父类相同的不变量,即其对象不变。但在iOS世界中,通常会返回一个可变版本,而不可变版本是预期的。当返回的对象像您所描述的那样在返回后改变可变对象时会出现问题。就我而言,具有另一个名称变量的私有属性将是唯一有趣的。调用者应该能够根据公开的类型发送消息,但不能针对子类型。我更新了我的问题,以更好地反映这一点。我们正在使用您的第三种方式,因为我们有一个经常变化的大数组。但是回到属性,您将如何以这种方式在内部使用属性?你认为用另一个名字命名的私有属性是最好的选择吗?顺便说一句,可变类作为非可换类的子类已经被证明是非常实用的,这让我很困惑。它实际上没有遵循继承规则。子类必须遵循与其父类相同的不变量,即其对象不变。但在iOS世界中,通常会返回一个可变版本,而不可变版本是预期的。如您所述,当返回对象在返回后更改可变对象时,会出现问题。
@interface SomeObject : NSObject
@property (readonly) id myProperty;
@end
@interface SomeObject ()
@property (readwrite) NSString *myInternalProperty;
@end

@implementation SomeObject
- (id)myProperty {
  return myInternalProperty;
}
@end
@class MyOpaque;
@interface SomeObject : NSObject
@property (readonly) MyOpaque *myProperty;
@end
@interface MyOpaque : NSString
@end
@implementation MyOpaque
@end

@implementation SomeObject
@end