There is a constant I'm using from the iOS SDK. I printed out the value of the constant (which were int's) and it was 0. Can I assume that constant will always remain zero between iOS builds? The reason I need to use the actual value and not the constant directly is because I want to keep it in a plist that ships in the main bundle. And since a plist doesn't take a constant variable name, I need to place a constant value in the plist.
You shouldn't assume an enum won't change its value, just to be safe, even though it probably won't. (They'll almost certainly keep it constant so old apps run correctly on future OS versions.)
Instead, save a string to your plist (say, "standard" under the key "map type"), and then initialize the actual value at runtime with an if statement. This has the added benefit of actually saying what you mean explicitly, which makes it easier to look at your plist (and your code!) and see what it does.
It's very likely that it will stay the same for at least the life of your application, if not longer.
Related
I'm flutter baby since last fall. When we use flutter types, they usually provide general features like toString(). One of them is '.runtimeType' But this 'getting runtimeType' method seems like not working on release mode, which is actually working well on debug mode.
Let's say that we've got normal map like Map amIMap = {"key": "is key", "value": "is value",};
Normally we think that the type of this var is 'Map', but print(amIMap.runtimeType); method in debug mode(which doesn't seem like working on release mode) print not 'Map' but something like LinkedHashMap, which might be in slightly different manner by dev environment but basically same concept of LinkedHashMap.
So here comes the question. In this link 'https://api.flutter.dev/flutter/dart-collection/LinkedHashMap-class.html', it seems like the printed type from above situation is something that Dart team actually intended, and it seems really like orderedDict in python. And through this question, i want to make sure that this concept of LinkedHashMap is safe to use. What i'm saying is that i want to know if the order of pairs with keys and their corresponding values safely remains same just like 'orderedDict' in python, REGARDLESS ON the environment like debug, profile, release mode, dartpad, and even platform like android, ios, macos, linux, window, web!
Since i've seen that runtimeType does not work well on release mode in my app, i'm afraid of that the order of the key-value pairs might be forgotten by the sdk in release mode, just like runtimeType method.
The reason why i'm asking this question is that i need to force the order of the pairs to be totally same as my dart code in IDEA, so that i can convert them into same format of json string then hashing the json strings, which all have exactly the same order of pairs, with crypto package's sha256 hashing method. The order of map must remain same before they get hashed. What makes me scared is that flutter tends to work differently environment by environment. Also when i use firestore plugin, i have to sort the map from firestore manually since they are not in the same order of the one which can be checked via firebase console. And it seems like these issues are in similar context. So i need bool value here if linkedHashMap is gonna save my maps' order of pairs even in release mode regardless on various platforms of flutter 2.0, just like orderedDict in python.
Hope anyone guru in this field answer this question with fully convinced experience. And i'd really appreciate for your comments if i left something unclear or even wrong in this question,
Thank you in advance [:
First, you should never use .runtimeType for anything other than debugging. As you have seen, the output is really not that stable and therefore very rarely be used for anything. You should instead use the is operator if you need to check if a given object is compatible with a given class.
Second, the Map() constructor (the {} syntax does the same) in Dart is documented to be creating an instance of LinkedHashMap. Since this is part of the standard SDK and language design, this is properly not going to change. Also, this behavior will be stable across all platforms where Dart is running.
But if you want to be sure you are always using a LinkedHashMap, you can just explicit create an instance of LinkedHashMap by importing the class from dart:collection.
LinkedHashMap is documented as:
The insertion order of keys is remembered, and keys are iterated in the order they were inserted into the map. Values are iterated in their corresponding key's order. Changing a key's value, when the key is already in the map, does not change the iteration order, but removing the key and adding it again will make it be last in the iteration order.
I have seen the use of set keyword in tcl often. This cannot be used to create constant. How does one create constant in tcl which can then be used by other procedures?
Generally speaking, most of the uses of constants fall into several categories:
enumeration values
magical numbers
looping control factors
scaling factors
In Tcl, for the first case you'd usually just use the name instead of mapping it to an integer, with integer mappings only being applied in the cases that need them. Even bit sets can be handled that way, substituting a list of names for the set of bits (and the name being present in the list is equivalent to the bit being set). Tcl's C API has relevant functions for helping with this, specifically Tcl_GetIndexFromObj().
Magical values are usually best locked away close to the code that handles them. If I was interfacing to hardware, I'd not let the magic values appear at all at the script level (since I'd have the binding code written in C).
Looping control factors are often best represented as default values for procedure arguments, as they are things that you want to sometimes override. But they're often not as needed once custom control structures are available, and they fit a lot more into the Tcl style of working.
Scaling factors are the case where constants might be useful. I tend to simulate those by just using a global or namespace variable and plain old not assigning to it from elsewhere. I'd be quite interested in having code to allow constants (specifically variables that can't be assigned to) as a standard feature, but we don't have that right now.
Once those cases are covered, what remain tend to be unimportant constants. After all, there's almost no need to calculate the sizes of things for allocation and stuff like that, and things like positional binding in SQL statements are discouraged within TDBC in favour of binding by name (an awful lot easier to get right).
A simple way of making a constant is to put a write trace on a variable so that whenever it is written to, it is reset back to its constant value.
set CONSTANT 123
trace add variable CONSTANT write {apply {args {
global CONSTANT
# Reset to the constant value; write traces are after the fact
set CONSTANT 123
# Make the write give an error
error "may not change constant"
}}}
I know this might be a silly question which I am asking, but I am really curious about this, since I am not having much knowledge of computer architecture.
Suppose I have a Register R1 and say I loaded value of a variable say LOCK=5 into the register, so now R1 has the value 5 stored into it, now let's suppose I updated the value of LOCK to 10 after some time, so will the value of register still be 5 or will it be updated.
When it comes to register based CPU architectures, I think Neo from the matrix has a valueable lession: "There are no variables."
Variables, as you're using them in a higher level programming languages are an abstract thing for describing to the compiler what operations to do a particular piece of data. That data may reside in system memory, or for temporary values never leave the register file.
However once the program has been compiled to a binary, there no longer are variables! For debugging purposes the compiler may annotate the code with information of the kind "at this particular position in the code, what is referred to as variable 'x' right now happens to be held in …".
I think the best way to understand this is to compile some very simple programs and look at their respective assembly, to see how things fit together. The Godbolt Compiler Explorer is a really valuable tool, here.
-willTurnIntoFault or -didTurnIntoFault? I guess it's stupid to release properties in both of them, so I must choose one. Which is the best?
The object is not "gone" when turned into a fault. It is reduced to its smallest size (just an empty object with an -objectID). If you are doing something in the -didTurnIntoFault that causes a property to be touched you would reverse the fault which is bad.
If your clean up requires touching a property you should do it in the -willTurnIntoFault. Otherwise it is pretty irrelevant which you choose.
The former is invoked just BEFORE the object is turned into a fault, the latter just AFTER. What kind of custom non-managed properties are you referring to? The choice may depend on this.
In my iPhone app I employ NSDecimalNumber to store some some currency rate values.
I pull the data from the web the first time the app is launched and then again when they become obsolete, and I store them in a NSDictionary; then I use writeToFile:atomically:.
When the app is launched for the first time, my rate conversion method works allright. Yet, when I launch the app a second time, and the rates get loaded with -(NSDictionary*) initWithContentsOfFile: the conversion methos stops working, and I get weird results.
I did some debug with breakpoints in the incriminated method, and I found out that the rates data are seen as NSCFNumber, rather than as NSDecimalNumber. So it appears that initWithContentsOfFile doesn't assign the right class to my objects. For the record, the actual value of these objects, as shown in the description method, corresponds to the expected rate value.
I also checked the plist file generated by writeToFile:atomically:, and saw that the rates are stored as real; I wonder whether this is the right type.
Any idea of whats going on?
Thanks in advance,
Davide
Property lists don't distinguish between decimal numbers and floating-point numbers. The real element holds a floating-point number. (Indeed, the serialization itself may simply be NSNumber sending floatValue to itself, unaware that the instance is actually of a subclass. That would mean the conversion to floating-point happens when you generate the plist data, not when you read it back in.)
You'll have to store it as a string, I think. Hopefully, that's lossless.
Plists only work with certain data types and NSNumber is one of those. If you want the NSDecimalNumber then you have two ways to go about it. The first is to keep using plists and then convert all the NSNumbers to NSDecimalNumbers after load. The second is to switch to using NSKeyedArchiver for storing data. This requires more code but means that if you save an NSDecimalNumber, you'll get an NSDecimalNumber back.