我的一些模型具有可选属性。我试图编写一种可以评估它们是否已经设置的方法。
以下是尝试,但我无法弄清楚如何从Any
对象中确定零值[编辑:( child
变量的类型为Any
} )]。它没有编译。
func allPropertiesHaveValues(obj: AnyObject) -> Bool {
let mirror = Mirror(reflecting: obj)
for child in mirror.children {
let value = child.value
if let optionalValue = value as? AnyObject? { //Does not compile
if optionalValue == nil {
return false
}
}
}
return true
}
修改
我忘了澄清上例中的child
值始终为Any
类型。 Any
类型很难,因为它无法与nil
进行比较,而AnyObject
的强制转换始终会失败。我试图在下面的操场上说明它。
var anyArray = [Any]();
var optionalStringWithValue: String? = "foo";
anyArray.append(optionalStringWithValue);
var nilOptional: String?
anyArray.append(nilOptional)
print(anyArray[0]); // "Optional("foo")\n"
print(anyArray[1]); // "nil\n"
if let optionalString = anyArray[0] as? AnyObject {
//will always fail
print("success")
}
//if anyArray[1] == nil { // will not compile
//}
答案 0 :(得分:4)
<强>过时:强>
您只需检查可选值是否为零:
func allPropertiesHaveValues(obj: AnyObject) -> Bool {
let mirror = Mirror(reflecting: obj)
for child in mirror.children {
//child.value being an optional
if child.value == nil {
return false
}
}
return true
}
修改强>
使用反射来检查Any
对象是否是可选的并包含值:
let optionalString : String? = "optional string"
let any : Any = optionalString
//First you will need to create a mirror of the any object
let mirror = Mirror(reflecting : any)
//Then you can check the display style to see if it's an optional
if mirror.displayStyle == .Optional {
//If it is, check the count of its children to see if there is a value or not
if mirror.children.count == 0 {
print("I don't have a value")
}
else {
print("I have a value")
}
}
这是一个游乐场示例(基于你的):
var anyArray = [Any]()
var optionalStringWithValue: String? = "foo"
anyArray.append(optionalStringWithValue)
var nilOptional: String?
anyArray.append(nilOptional)
let string = "string not optional"
anyArray.append(string)
print(anyArray[0]) // "Optional("foo")\n"
print(anyArray[1]) // "nil\n"
print(anyArray[2]) // "string not optional\n"
let mirrorOptionalWithValue = Mirror(reflecting: anyArray[0])
if mirrorOptionalWithValue.displayStyle == .Optional
&& mirrorOptionalWithValue.children.count == 1 {
print("Is an optional and contains a value")
}
let mirrorOptionalWithoutValue = Mirror(reflecting: anyArray[1])
if mirrorOptionalWithoutValue.displayStyle == .Optional &&
mirrorOptionalWithoutValue.children.count == 0 {
print("Is an optional but is nil")
}
let mirrorNotAnOptional = Mirror(reflecting: anyArray[2])
if mirrorNotAnOptional.displayStyle != .Optional {
print("Is not an optional")
}
答案 1 :(得分:3)
我使用了反映Any
值的@ebluehands技术来修改原始函数。它使用初始镜像循环遍历属性,然后使用displayStyle
单独反映每个属性以确定属性是否是可选的。
func allPropertiesHaveValues(obj: AnyObject) -> Bool {
let mirror = Mirror(reflecting: obj)
for child in mirror.children {
let value: Any = child.value
let subMirror = Mirror(reflecting: value)
if subMirror.displayStyle == .Optional {
if subMirror.children.count == 0 {
return false
}
}
}
return true
}
答案 2 :(得分:0)
另一个选择是创建扩展名。
extension NSManagedObject {
func checkIfAllRequiredMembersAreSet() -> Bool {
let attributes = self.entity.attributesByName
for (attribute, value) in attributes {
if value.attributeValueClassName != nil {
let v: AnyObject? = self.valueForKey(attribute)
if !value.optional && v != nil {
return false
}
}
}
return true
}
}
答案 3 :(得分:0)
根据this answer,我建议使用var main = myApp.controller("main", ['$scope', function ($scope) {
/*
Include the following two lines in index.html head
<script src='build/pdfmake.min.js'></script>
<script src='build/vfs_fonts.js'></script>
After that in your angularjs controller you can write the following lines to implement a function.
getPdf in the controller scope. This can be attached to a button click using ng-click and it will
download the pdf with the image.
eg.
<div ng-controller="main">
<button ng-click="getPdf()">Get PDF</button>
</div>
*/
$scope.image = "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";
$scope.getPdf = function(){
var imageContentDefinition = {
content: [
{
image: 'data:image/jpeg;base64,' + $scope.image
}
]};
pdfMake.createPdf(imageContentDefinition).download("yourpdf.pdf");
};
}]);
。
我最近做了一些事情,以确保我至少有一个可选集。这是一个确保所有设置都已确定的示例。你可以粘贴到游乐场:
if case Optional<Any>.some(_)