I have an interesting query with regard to #MainActor and strict concurrency checking (-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks)
I have functions (Eg, Analytics) that at the lowest level require access to the device screen scale UIScreen.main.scale which is isolated to MainActor. However I would prefer not to have to declare the entire stack of functions above the one that accesses scale as requiring MainActor.
Is there a way to do this, or do I have no other options?
How would be the best way to ensure my code only ever calls UIScreen once and keeps the result available for next time without manually defining a var and checking if its nil? Ie is there a kind of computed property that will do this?
Edit: Is there an equivalent of this using MainActor (MainActor.run doesn't do the same thing; it seems to block synchronously):
DispatchQueue.main.async {
Thanks,
Chris
Non-UI code should not rely directly on UIScreen. The scale (for example), should be passed as a parameter, or to actors in their init. If the scale changes (which it can, when screens are added or removed), then the new value should be sent to the actor. Or the actor can observe something that publishes the scale when it changes.
The key point is accessing UIScreen from a random thread is not valid for a reason. The scale can in fact change at any time. Reading it from an actor is and should be an async call.
It sounds like you have some kind of Analytics actor. The simplest implementation of this would be to just pass the scale when you create it.
ngOnChanges is deprecated in favour of ngAfterChanges, but the former was given a list of properties that changed. The latter gets nothing. How do I know what changed so I can only perform expensive actions if a particular #Input changed?
Calculating the list of changes was actually expensive itself. So it was dropped instead I would suggest having a setter mark if something has changed for just the expensive inputs.
We've started using VirtualTreeView v5.5.3 with Delphi7 since 1 year and love it!
We would like to use the full potential of the component, but there is only a little information about the BeginSynch method in the help file.
When should BeginSynch + EndSynch be used compared to BeginUpdate + EndUpdate?
Which one should be nested into the other?
What methods can be used in which case? (Sort, ScrollIntoView, MoveTo, NodeHeight, isVisible[], ... ) to group manipulations before painting to speed up the app?
To my understanding they have different, almost opposite purposes, and for your use case you would need BeginUpdate.
BeginUpdate is typically called when you want to do a lot of updates, and you don't want redrawing etc to happen during that process. Many controls, including TListBox and TDBGrid, have this possibility to speed up bulk updates.
BeginSynch is related to events, especially the OnChange event. The VirtualTreeView can fire the OnChange event with some delay when you set the ChangeDelay property to a value higher than 0.
This also means that you may miss some events. If you make two changes in rapid succession, you may only get one event, or you may get the event later than desired.
BeginSynch will start a synchronous mode that fires the OnChange event immediately after (in sync with) the change being made, overriding the ChangeDelay property. Starting this sync mode is easier than saving the value of the ChangeDelay property and restoring it afterwards.
So in a way, you could say that BeginUpdate and BeginSync are almost opposites of each other, in terms of speed, but really it's just about what your usecase is. For your case ("grouping manipulations") you would definitely use BeginUpdate.
The documentation on BeginSynch could be a bit more clear in this regard. It refers to BeginUpdate because it's a similar kind of mechanism (entering some kind of update mode, with a correlating EndSomething method), while actually it should refer to ChangeDelay which it is functionally related to. It's also interesting that the 'Send feedback' link at the bottom of the documentation is not actually a link...
Lets say i have a UISegmentedSwitch for the User to set Metric or Imperial Measure
I could then test for its state in various part of the code,
but if the condition was what i thought it was, have i wasted my time (and cycles) in the asking?
In other languages I have normally set a variable/flag as a multiplier, the default being 1, ( no change as a result) and the other being what conversion is required ( e.g. 3.048 ).
that way there is no need to test, and if there are other things happening at the calculation its not an additional nesting of methods.
But does it get into global variable territory? Is it so bad if there is only one such flag even though it will be required in a number of places?
Perhaps I should create a custom class with just one property, or make it a property of the viewController, but is the cpu processing involved in all that just as taxing on battery life or UI responsiveness?
whats 'the usual' here?
There are those who believe that global variables are evil, and like most anything else, if they're abused they can be. But the idea that a variable like this shouldn't be made global is silly.
If you're going to be using it heavily and restricting it to read-only except for the one location, I'd forget the naysayers and go with it. If it isn't going to be that heavily referenced, you could make it a property that gets passed around from class to class, but that is a pain.
Another alternative is a singleton to hold "globals" as shown here:
http://maniacdev.com/2009/07/global-variables-in-iphone-objective-c/
IMO, the excitement about occasional use of globals is overdone. There are times and places where it just makes sense.
I think the "normal" here would be to use [NSUserDefaults standardUserDefaults] and have it persist.
You are making decisions in the code in other places based on this value. It would also seem likely you would like to have this value persist between uses of the App, so that their choice would be maintained.
Referring to it as [[NSUserDefaults standardUserDefaults] boolForKey:kUsesMetric]; is what would be "the norm" in my programming group.
I've been a bad programmer because I am doing a copy and paste. An example is that everytime i connect to a database and retrieve a recordset, I will copy the previous code and edit, copy the code that sets the datagridview and edit. I am aware of the phrase code reuse, but I have not actually used it. How can i utilize code reuse so that I don't have to copy and paste the database code and the datagridview code.,
The essence of code reuse is to take a common operation and parameterize it so it can accept a variety of inputs.
Take humble printf, for example. Imagine if you did not have printf, and only had write, or something similar:
//convert theInt to a string and write it out.
char c[24];
itoa(theInt, c, 10);
puts(c);
Now this sucks to have to write every time, and is actually kind of buggy. So some smart programmer decided he was tired of this and wrote a better function, that in one fell swoop print stuff to stdout.
printf("%d", theInt);
You don't need to get as fancy as printf with it's variadic arguments and format string. Even just a simple routine such as:
void print_int(int theInt)
{
char c[24];
itoa(theInt, c, 10);
puts(c);
}
would do the trick nickely. This way, if you want to change print_int to always print to stderr you could update it to be:
void print_int(int theInt)
{
fprintf(stderr, "%d", theInt);
}
and all your integers would now magically be printed to standard error.
You could even then bundle that function and others you write up into a library, which is just a collection of code you can load in to your program.
Following the practice of code reuse is why you even have a database to connect to: someone created some code to store records on disk, reworked it until it was usable by others, and decided to call it a database.
Libraries do not magically appear. They are created by programmers to make their lives easier and to allow them to work faster.
Put the code into a routine and call the routine whenever you want that code to be executed.
Check out Martin Fowler's book on refactoring, or some of the numerous refactoring related internet resources (also on stackoverflow), to find out how you could improve code that has smells of duplication.
At first, create a library with reusable functions. They can be linked with different applications. It saves a lot of time and encourages reuse.
Also be sure the library is unit tested and documented. So it is very easy to find the right class/function/variable/constant.
Good rule of thumb is if you use same piece three times, and it's obviously possible to generalize it, than make it a procedure/function/library.
However, as I am getting older, and also more experienced as a professional developer, I am more inclined to see code reuse as not always the best idea, for two reasons:
It's difficult to anticipate future needs, so it's very hard to define APIs so you would really use them next time. It can cost you twice as much time - once you make it more general just so that second time you are going to rewrite it anyway. It seems to me that especially Java projects of late are prone to this, they seem to be always rewritten in the framework du jour, just to be more "easier to integrate" or whatever in the future.
In a larger organization (I am a member of one), if you have to rely on some external team (either in-house or 3rd party), you can have a problem. Your future then depends on their funding and their resources. So it can be a big burden to use foreign code or library. In a similar fashion, if you share a piece of code to some other team, they can then expect that you will maintain it.
Note however, these are more like business reasons, so in open source, it's almost invariably a good thing to be reusable.
to get code reuse you need to become a master of...
Giving things names that capture their essence. This is really really important
Making sure that it only does one thing. This is really comes back to the first point, if you can't name it by its essence, then often its doing too much.
Locating the thing somewhere logical. Again this comes back to being able to name things well and capturing its essence...
Grouping it with things that build on a central concept. Same as above, but said differntly :-)
The first thing to note is that by using copy-and-paste, you are reusing code - albeit not in the most efficient way.
You have recognised a situation where you have come up with a solution previously.
There are two main scopes that you need to be aware of when thinking about code reuse. Firstly, code reuse within a project and, secondly, code reuse between projects.
The fact that you have a piece of code that you can copy and paste within a project should be a cue that the piece of code that you're looking at is useful elsewhere. That is the time to make it into a function, and make it available within the project.
Ideally you should replace all occurrances of that code with your new function, so that it (a) reduces redundant code and (b) ensures that any bugs in that chunk of code only need to be fixed in one function instead of many.
The second scope, code reuse across projects, requires some more organisation to get the maximum benefit. This issue has been addressed in a couple of other SO questions eg. here and here.
A good start is to organise code that is likely to be reused across projects into source files that are as self-contained as possible. Minimise the amount of supporting, project specific, code that is required as this will make it easier to reuse entire files in a new project. This means minimising the use of project specific data-types, minimising the use project specific global variables, etc.
This may mean creating utility files that contain functions that you know are going to be useful in your environment. eg. Common database functions if you often develop projects that depend on databases.
I think the best way to answer your problem is that create a separate assembly for your important functions.. in this way you can create extension methods or modify the helper assemble itself.. think of this function..
ExportToExcel(List date, string filename)
this method can be use for your future excel export functions so why don't store it in your own helper assembly.. i this way you just add reference to these assemblies.
Depending on the size of the project can change the answer.
For a smaller project I would recommend setting up a DatabaseHelper class that does all your DB access. It would just be a wrapper around opening/closing connections and execution of the DB code. Then at a higher level you can just write the DBCommands that will be executed.
A similar technique could be used for a larger project, but would need some additional work, interfaces need to be added, DI, as well as abstracting out what you need to know about the database.
You might also try looking into ORM, DAAB, or over to the Patterns and Practices Group
As far as how to prevent the ole C&P? - Well as you write your code, you need to periodically review it, if you have similar blocks of code, that only vary by a parameter or two, that is always a good candidate for refactoring into its own method.
Now for my pseudo code example:
Function GetCustomer(ID) as Customer
Dim CMD as New DBCmd("SQL or Stored Proc")
CMD.Paramaters.Add("CustID",DBType,Length).Value = ID
Dim DHelper as New DatabaseHelper
DR = DHelper.GetReader(CMD)
Dim RtnCust as New Customer(Dx)
Return RtnCust
End Function
Class DataHelper
Public Function GetDataTable(cmd) as DataTable
Write the DB access code stuff here.
GetConnectionString
OpenConnection
Do DB Operation
Close Connection
End Function
Public Function GetDataReader(cmd) as DataReader
Public Function GetDataSet(cmd) as DataSet
... And So on ...
End Class
For the example you give, the appropriate solution is to write a function that takes as parameters whatever it is that you edit whenever you paste the block, then call that function with the appropriate data as parameters.
Try and get into the habit of using other people's functions and libraries.
You'll usually find that your particular problem has a well-tested, elegant solution.
Even if the solutions you find aren't a perfect fit, you'll probably gain a lot of insight into the problem by seeing how other people have tackled it.
I'll do this at two levels. First within a class or namespace, put that code piece that is reused in that scope in a separate method and make sure it is being called.
Second is something similar to the case that you are describing. That is a good candidate to be put in a library or a helper/utility class that can be reused more broadly.
It is important to evaluate everything that you are doing with an perspective whether it can be made available to others for reuse. This should be a fundamental approach to programming that most of us dont realize.
Note that anything that is to be reused needs to be documented in more detail. Its naming convention be distinct, all the parameters, return results and any constraints/limitations/pre-requisites that are needed should be clearly documented (in code or help files).
It depends somewhat on what programming language you're using. In most languages you can
Write a function, parameterize it to allow variations
Write a function object, with members to hold the varying data
Develop a hierarchy of (function object?) classes that implement even more complicated variations
In C++ you could also develop templates to generate the various functions or classes at compile time
Easy: whenever you catch yourself copy-pasting code, take it out immediately (i.e., don't do it after you've already CP'd code several times) into a new function.