除了'var'(see my other post here)之外,我真正喜欢C#的一个原因是我可以声明,然后使用大括号初始化类的成员,就像这样......
var reallyLongFooVarName = new ReallyLongFooClassName(){
Name = "I'm an instance of Foo",
ID = 23 };
甚至在一行上,就像这样...
var longFooVarName = new ReallyLongFooClassName(){ Name = "I'm an instance of Foo", ID = 23 };
这将创建ReallyLongFooClassName的实例,然后将其成员的名称设置为“ID”。
这就像你输入的那样编译...
ReallyLongFooClassName reallyLongFooVarName = new ReallyLongFooClassName();
reallyLongFooVarName.Name = "I'm an instance of Foo";
reallyLongFooVarName.ID = 23;
Objective-C / C ++是否有与C#的member-brace-initialization相同的东西?
注意:感谢我的其他帖子,我已经知道'auto'是Objective-C ++中的'var'等价物,但Objective-C没有任何这样的等价,这是一种耻辱。再次,see my other post here获取更多信息。)
我知道写初始化器。这完全是一个不同的节拍。我在上面演示的技术在C#中使用属性的setter,或者直接设置成员变量而不必编写构造函数(它们等同于Objective-C的'init'成员。)必须编写init成员强制你必须预先指定您要设置的内容。成员大括号初始化允许您以任何您想要的顺序指定属性/成员变量的任意组合。同样,它只是一次编写多行代码的语法糖。它实际上并没有改变课程。
答案 0 :(得分:1)
如果您考虑使用Objective C / C ++,有几种选择。
目标C:
在A类中创建初始化方法为;
@interface ClassA:NSObject
-(id)initWithName:(NSString*)name id:(NSUinteger)id;
@end
@implementation ClassA{
NSString *name;
NSUinterger id;
}
-(id)initWithName:(NSString*)name id:(NSUInteger)id{
self = [super init];
if(!self)
return nil;
self -> name = name;
self -> id = id;
return self;
}
初始化;
[[ClassA alloc] initWithName:@"MyName" id:1000];
Objective C alternative,
使用类或结构;
使用struct;
struct MyClass{
NSString *name;
NSString *identifier;
MyClass(NSString *name, NSUInteger identifier):name(name), identifier(identifier);
};
Initilializing;
MyClass *myclass = new MyClass(@"Sandeep", 1000);
使用class;
class MyClass{
private:
NSString *name;
NSString *identifier;
public:
MyClass(NSString *name = @"", NSUInteger identifier = 0);
};
我认为这应该是一些如何回答你的问题。
答案 1 :(得分:1)
您可以编写一个类似的辅助函数(在Objective-C ++中,但您可以通过Class
作为参数轻松地在Objective-C中执行此操作):
template<class T>
T* NewObject(NSDictionary *fields) {
static_assert(std::is_convertible<T*, id>::value,
"T must be an Objective-C class.");
auto* obj = [[[[T class] alloc] init] autorelease];
for (auto* key in fields.keys) {
auto* capitalizedKey =
[key stringByReplacingCharactersInRange:NSMakeRange(0, 1)
withString:[key substringToIndex:1].uppercaseString];
auto* message = [NSString stringWithFormat:@"set%@:", capitalizedKey];
[obj performSelector:NSSelectorFromString(message) withObject:fields[key]];
}
return obj;
}
然后按如下方式使用:
auto* object = NewObject<MyClass>(@{
@"foo": @"bar",
@"baz": @42
});
我没有测试过,但它应该可行。请注意,当setter使用非Objective-C对象(例如int
)时,它将不起作用,但是可以更改函数以使其工作(通过反射)。
答案 2 :(得分:0)
不,没有这样的设施。
Objective-C采用提供初始化程序的路径。通常,初始化程序获取初始化类实例所需的必需参数。有时,其中一些参数是可选的。即你可能有:
- (instancetype)initWithCar:(Car*)car tires:(NSArray*)tires cover:(Cover*)cover;
cover
有时可能是nil
。
在Objective-C中,类的实例通常用必需的状态初始化,以提供最小的工作实例,然后调用各种setter,然后进一步配置类。
答案 3 :(得分:0)
以下是ComponentKit中用于启发的几种方法:
{[CKLabelComponent
newWithLabelAttributes:{
.string = (indicatesSuccess ? @"Yes" : @"No"),
.color = [UIColor whiteColor],
.font = [UIFont fontWithName:@"Cochin-Bold" size:45.0],
.alignment = NSTextAlignmentCenter
}
viewAttributes:{
{@selector(setBackgroundColor:), [UIColor clearColor]},
{@selector(setUserInteractionEnabled:), @NO},
}]
},
您可以通过
获取可变数量的命名属性struct CKLabelAttributes
)std::unordered_map
(在本例中为typedef std::unordered_map<CKComponentViewAttribute, id>
),其中包含您要用于初始化课程的所有键和值。此语法避免了-initWithA:B:C:
,-initWithA:
,-initWithB:
,...爆炸,这种情况通常发生在复杂的Obj-C接口上。