This question already has answers here:
Xcode NSManagedObject subclass contains optionals when they are marked as non-optional
(4 answers)
Closed 4 years ago.
I set about an attribute it is NOT optional, but still when read value of it, it returns an optional variable, why?
What you set in your model may not directly correspond to what you have in your code. Consider that the model will work for multiple platforms (iOS, OSX) and for multiple languages (Swift, Objective-C).
Your classes are then autogenerated where in your case it seems you are using Swift. But they are subclasses of managed objects which are NSObject subclasses so on bottom you are on objectiveC. If I remember correctly all of these properties will be force-unwrapped which still means they are wrapped ergo optional when printed.
ObjectiveC has a bit different system of constructors and at some point each of the values/properties in an object will be null. Due to how CoreData works it might make sense to keep force-unwrapped values.
So a long story short: These two may not be as tightly connected as you believe. But you should not worry about that, if this breaks any of your functionality/code you should ask the question directly.
Related
(first noticed on: Xcode 8.2.1, iOS 10, Swift 3)
(still present as of: Xcode 9 beta 3, iOS11, Swift 4)
We all know that the Core Data concept of optionals precedes and is not strictly tied to the Swift concept of optionals.
And we have accepted that even if a Core Data attribute is marked as Non-optional, the auto-generated NSManagedObject subclass has an optional type:
(some people manually remove the ? with no adverse effects, some don't, but that's beside the point)
(From here on the example and screenshots are for Bool properties, but same goes for Int16/32/64, Double, Float)
Now I noticed the reverse - when a Core Data attribute of type Bool is marked as Optional (and Use Scalar Type is chosen, which Xcode does by default), the auto-generated class has a variable of a non-optional type.
Does this make sense? Is it a bug? Is the behaviour documented anywhere?
And most importantly - how do I actually represent an optional Bool?
I can think of some work-arounds, but they don't seem ideal (e.g. not using scalars, but going back to NSNumber representation of the Bool. Or (even worse) having a separate Bool called something like isVerified_isSet)
Note: I did a couple more tests and if the Default Value is set to None or to NO, then the variable gets saved as false (even if I never actually assign it in my code). If the Default Value is set to YES, then the variable gets saved as true. Still, this means that (apparently) there is no way to logically represent this variable as not having been set yet.
I see the same thing, and I consider it to be a bug. It's not documented anywhere that I can find. Apparently Core Data is applying Objective-C style assumptions here, where a boolean defaults to NO, and an integer defaults to 0. The Core Data/Swift interface has some rough edges, and this is one I hadn't considered before.
It's a good find but I think you're stuck with it until Apple addresses it. You already know the best workarounds, which I agree aren't great. I recommend filing a bug.
This happens because Objective-C scalar types do not have a notion of nil value. Source: handling-core-data-optional-scalar-attributes
I would rather use Objective-C types to manage these cases than Swift types.
In these cases, for scalars types, you can use NSNumber.
#NSManaged public var myDouble: NSNumber?
In the model myDouble is an optional double with nil value by default.
To get the real value you only need to use:
myEntity.myDouble?.doubleValue
If you end up here with this:
#NSManaged var boolAttribute: Bool
and it is not being seen in Objective-C, and you have already disabled "Optional" and enabled "Use Scalar Type" on those attributes, then do yourself a favour.
Double check you have imported your Swift bridging header into that Objective-C file.
I did not and, well, I was most of the way to changing my Bools to NSNumbers before smacking my head and realising how foolish I had been.
This question already has answers here:
How can I find out the Objective-C generics type?
(2 answers)
Closed 7 years ago.
Is there any ways in objective-c to find type of property which is declareted in next way:
#property(nonatomic, strong) NSArray<CustomClass *> *array;
I can get type of this property as NSArray, but are any ways to get CustomClass type?
Thanks in advance.
There is no way to receive information about generics declaration in runtime. Objective-C generics is a recent addition to language. They are used for compile-time checks only, so no any additional runtime information created. Note, that generic declaration doesn't strictly prevent storing objects of other class in array - compiler warning may be suppressed, although it's a bad practice.
But, there is still a possibility to determine classes of objects, stored in array. For example, you can use code like [array valueForKey:#"class"] to receive array of classes, corresponding to each element.
Type hints in lightweight generics are mainly used by compilers to raise warnings and it will not be available during runtime.
This SO link provides additional information and references to Apple docs/ videos. For convenience, I'm adding some information here.
So the entire lightweight generics feature is based on a type erasure model. Which means that the compiler has all of this rich static type information but it erases that information when generating code.
This question already has answers here:
Objective-C: Use singleton vs. use class as an object?
(3 answers)
Closed 8 years ago.
It seems we always use a sharedInstance class variable to access the Singleton and perform methods on it. But why don't we just make all operations class methods and not have a variable to deal with at all? [SingletonClass uploadFile:(NSFile *)file] instead of [[SingletonClass sharedInstance] uploadFile:(NSFile *)file] (or the Swift equivalent).
What benefits do the variable bring? Or am I just overlooking some very integral concept in Singletons that not having a variable would prevent?
Furthermore, what stops this variable from being deallocated by memory? I know it's only created once, but why doesn't it ever get removed?
You create a shared instance if you need to be able to store state. If you can get away with just class methods, that is definitely preferable. The less state you have in your app, especially with singletons, the fewer bugs you will create.
I understand how to use NSCoding to convert my objects to archive objects. That's not my question.
What I'm wondering is why there isn't a default implementation of NSCoding that could handle probably 99% of cases.
For instance, every time I write a custom class that I want to archive, I perform the following:
Implement -(void)encodeWithCoder: and -(id)initWithCoder:.
Go down my property list, writing a pair of statements (one encode, one decode) for each property.
If the property is an object, I use the encode/decodeObject method.
If the property is a value, I use the corresponding encode/decode method.
I always use the property's name as my key.
I would suspect that almost every implementation of NSCoding is exactly like mine, with the only changes being the particular properties that need to be manipulated.
It seems to me that this would be a perfect place for a standard implementation, with the option to override if your particular case if funky.
Do I have a misunderstanding of what's going on? If not, could I add a category on NSObject to implement this common method on all objects in my projects?
I suspect that the answer to your question is simply that NSCoding was designed long before Objective-C properties existed. (NSCoding was part of the OpenStep spec in 1994, whereas properties arrived with Objective-C 2.0 in 2007.) Additionally, some classes have properties that are not appropriate to be serialized for later.
However, your proposed solution could be a great time-saver! At least one such solution already exists. Check out AutoCoding.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective-C - When to use 'self'
I needed a variable to be passed from one view to another so I made a property called StringC in the .h and accessed it using self.StringC (that part worked).
I also need some arrays that are accessible throughout the view but I'm using them differently.
For instance I have lvLabelArray and I'm using
self.lvLabelArray=[[NSMutableArray alloc]init];
and then later I'm using
[lvLabelArray addObject:LabelText];
Is there a difference between that and
[self.lvLabelArray addObject:LabelText];
?
Sorry I don't know the terms for those kinds of variables.
There is an important difference there.
self.attribute goes through the object's getter or setter function, as appropriate. That allows you to set up initial values, trigger update messages, or anything else.
Accessing "attribute" directly goes straight to the underlying variable, so you bypass all that. As a result, it's definitely the less-preferable way of working.
A common way of avoiding this confusion, and just plain mistakes, is to rename the underlying variable. Instead of just "#synthesize attribute", use "#synthesize attribute = _attribute". This will create the getter and setter methods as before, but they'll the underlying variable is named "_attribute". That means that trying to use "attribute" without "self" will trigger a compiler error.