I'm developing a simple game in swift, but using GamePlayer (on Cydia, a cheat-enginelike), I am able to locate, track and modify my score.
I was wondering how can I prevent this kind of cheats... I tried to create a new instance of the element whenever it changes, example:
score = Int(score + 1)
I also tried to reset the var to nil and re-assign it:
let tmp = score + 1
score = nil
score = tmp
But it is not working...
My first question is: Is it possible to change a variable's address in swift ? And will it prevent address tracking?
My second question is: Another thing that can work, encoding my score, but is it worth the work ?
You can put your score variable in a struct and use copy-on-write. Then, when you change a value, you get a fresh copy of the score. The possibilities and how copy-on-write works, is described here with examples: copy-on-write
Compared to the solution, were you actually encrypt the number it has advantages and disadvantages. Just some of them from the top of my head (I'm curious what your points are)
encryption needs more cpu power and therefore more battery. Whereas the copy-on-write is implemented deep on iOS level, where we can assume, that it is very well optimised.
The copy-on-write solution is less secure, as one might find the right address just at the beginning and can track it (now, that I think about it, not really...)
The copy-on-write adds more complexity to your source code as you need to trigger it on every change.
Related
What is the maximum number of state variables I can have in a Swift UI Struct ?
struct Example: View {
#State var first : Bool = true
#State var second: Double = 94.4
#State var third: CGFloat = 45.45
.
.
.
How many maximum ?
var body: some View {
Text("Hello ")
}
}
Also, does having a lot of state variables actually slow down the app ? I need some clarity on the scalability of this thing cuz I am new to declarative programming :P
Just to get you started with an answer,
It's hard to believe there is any performance issue. "Declarative programming" doesn't actually exist. It's just a compiler / runtime / whatever doing some checking. There's no really substantative, paradigm difference from other structures in the pipeline.
If, incredibly, you were doing real performance programming, perhaps scientific or for a game or the like, you'd never in a million years be involved in anything like this, so it's of no relevance.
Also, it's worth nothing that anything at all related to UI on your phone, uses a staggering amount of processing power. Rendering any one text character! which happens to be on screen at that time, is an amazing dance of spline curve dithering, blitting, etc. Issue such as "checking done by the runtime system" are really irrelevant except in incredibly unusual cases.
Summary: don't consider performance in this milieu.
How many can you have? If you paste in a few thousand, it works fine. It's hard to believe there's any limit.
Summary: It's possible you're thinking of a limit like "30". There is no such limit whatsoever.
(There could be some technical, arcane limit - like 64 million - but it's totally irrelevant to what you're doing!)
Management summary: relax and enjoy, these are non-issues.
More info on the particular case
I am trying to animate, i am using withAnimation to display percentage progress in a ring
For the number of state variables described (say, anything less than 100,000 - you are using about "20"), the extra overhead for the checking is utterly irrelevant. It is so low you could not measure it.
TBC this is likely not the most elegant way to do this but, regarding the specific performance question asked, it is absolutely a non-issue. Enjoy!
Not sure if this is a bug but I've reached the limits of SwiftUI with an app that has 85 #State variables on 1 screen. Also I have a lot of stacked groups inside groups inside groups. I'm at the stage where if I add any 1 line of code, the compiler will complains that what I'm writing is not a View.
So there is a limit depending on how fast your computer can compile the View.
The compiler has a set amount of time it is allowed to try and compile until it just stops abruptly.
I got the same problem, when I try to put one more state, it does not compile:
(372, 10) The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
but when remove any state and use the new one it works. So definitely it has the limits!!! Another question is how to solve it.
How do I make a TextLabel's text update to a variable?
I have tried setting the text to "score: ", _G.score
but it won't update with the variable, and yes I do set the text after the variable has updated.
Code:
script.Parent.mouseClick:connect(function()
_G.score = _G.score + 1
game.StarterGui.ScreenGui.TextLabel.Text = _G.score
end)
game.StarterGui is actually a template GUI, and every time a player joins the game, a copy of it is made and given to the new player. Thus, if you try to modify it, you will not be actually modifying the copies of it that were given to all the players.
There are two solutions to this problem:
Only use relative paths—that being, only use paths to GUI objects that begin with "script." just like you said script.Parent.mouseClick:connect(…).
Iterate through all the copies that have been given out to the players. This can be found under each Player object's .PlayerGui.
You should almost never do the latter. Here's how you can decide:
If you have code that is found within the StarterGui (rather than in the Workspace or something), then you should use the former. This is because when the StarterGui gets copied into a new player's GUI (called a PlayerGui), that script will get copied along with it since it was inside of the StarterGui. Thus, a relative path like script.Parent.Something.SomethingElse.Text = "hi" will be valid; it will affect that PlayerGui.
If you have some code that is not within the StarterGui (like if it's in the Workspace), then you must use the latter. This is because such a script will not get copied into each player's PlayerGui. As a result, you must go through each player's PlayerGui in a for loop or something similar. This scenario is very rarely the case, and if it ever is, consider trying to make it not the case if possible because this is a very hairy situation to try to deal with; you have to account for special circumstances like the possibility that a player hasn't gotten a copy of the StarterGui yet.
Please let me know if this explanation was in any way confusing; I'll try my best to explain it better.
You can find some visuals to go along with this explanation and some further reading on the official ROBLOX Wiki's explanation of this topic here: "Player vs. Starter GUIs".
My implementation of the MVVM pattern with RxSwift, Realm and RxRealm looks like this:
E.g. I have a textfield that shows some editable content. I want this to be realtime saved/synched to the DB like this:
//View
textField.rx.text.subscribe(textViewModel.saveText.inputs)
viewModel.stringValue.drive(textField.rx.text)
//ViewModel:
lazy var saveText = Action<String,Void>{ newStringValue in
realm.write{
textObject.stringValue = newStringValue
}
//don't block the main thread
return Observable.just()
}
lazy var stringValue = Observable(from:textObject).map{$0.stringValue}.asDriver(onErrorJustReturn : "no string")
When typing slowly in the TextField, everything works accordingly. When typing very quickly thought, letters get "swallowed" like this:
Type "A"
write "A" to DB
Type "B"
Receive "A" from DB
-> Textfield value becomes A instead of AB.
When working with realtime synchronization this is the desired behaviour. For single text typing this seems not a good solution. How would such a 2-way binding be properly implemented and the undesired effect be avoided, especially in a scenario where the viewModel is processing the text value before write or after read from the source?
In your requirements will the Realm stored data ever be updated via another source? As in, could you ever receive a value in the string that came from another field?
If not, then you may be able to trust your input, and your writes can be eventually consistent.
The problem, though, comes down to the speed of writes and the notification returning the data; small but not nothing. Perhaps an intermediary would be beneficial.
For example, write your input field out to value that will periodically synchronise to Realm. That way your observable can have immediate access to the updated value and you can trust that eventually the value will be
Happy to explore further to see if we can solve something. :)
Edit:
Realm's guidance on conflict resolution.
A manual approach might be to hold two values; one is the value you start with, the other is the value that is being managed by the server.
If the starting value and the server value differ, you have a conflict to manage. Your strategy can be to reject one, accept one or somehow merge them, depending on the complexity of the data.
When implementing algorithms and other things while trying to maintain reusability and separation patterns, I regularly get stuck in situations like this:
I communicate back and forth with an delegate while traversing a big graph of objects. My concern is how much all this messaging hurts, or how much I must care about Objective-C messaging overhead.
The alternative is to not separate anything and always put the individual code right into the algorithm like for example this graph traverser. But this would be nasty to maintain later and is not reusable.
So: Just to get an idea of how bad it really is: How many Objective-C messages can be sent in one second, on an iPhone 4?
Sure I could write a test but I don't want to get it biased by making every message increment a variable.
There's not really a constant number to be had. What if the phone is checking email in the background, or you have a background thread doing IO work?
The approach to take with things like this is, just do the simple thing first. Call delegates as you would, and see if performance is OK.
If it's not, then figure out how to improve things. If messaging is the overhead you could replace it with a plan C function call.
Taking the question implicitly to be "at what point do you sacrifice good design patterns for speed?", I'll add that you can eliminate many of the Objective-C costs while keeping most of the benefits of good design.
Objective-C's dynamic dispatch consults a table of some sort to map Objective-C selectors to the C-level implementations of those methods. It then performs the C function call, or drops back onto one of the backup mechanisms (eg, forwarding targets) and/or ends up throwing an exception if no such call exists. In situations where you've effectively got:
int c = 1000000;
while(c--)
{
[delegate something]; // one dynamic dispatch per loop iteration
}
(which is ridiculously artificial, but you get the point), you can instead perform:
int c = 1000000;
IMP methodToCall = [delegate methodForSelector:#selector(something)];
while(c--)
{
methodToCall(delegate, #selector(something));
// one C function call per loop iteration, and
// delegate probably doesn't know the difference
}
What you've done there is taken the dynamic part of the dispatch — the C function lookup — outside the inner loop. So you've lost many dynamic benefits. 'delegate' can't method swizzle during the loop, with the side effect that you've potentially broken key-value observing, and all of the backup mechanisms won't work. But what you've managed to do is pull the dynamic stuff out of the loop.
Since it's ugly and defeats many of the Objective-C mechanisms, I'd consider this bad practice in the general case. The main place I'd recommend it is when you have a tightly constrained class or set of classes hidden somewhere behind the facade pattern (so, you know in advance exactly who will communicate with whom and under what circumstances) and you're able to prove definitively that dynamic dispatch is costing you significantly.
For full details of the inner workings at the C level, see the Objective-C Runtime Reference. You can then cross-check that against the NSObject class reference to see where convenience methods are provided for getting some bits of information (such as the IMP I use in the example).
I am trying to determine if an object is valid. The program has (at least) two threads and one of the threads might invalidate the object by removing it from an NSMutableArray. I need the other thread to check either its existence or validity before acting on it.
You can't. The only way to check if the memory your object pointer has still represents a valid object is to dereference it, but dereferencing an "invalid" object (by which I assume you mean one that has been dealloced) will result in either accessing the memory of a new object that has been allocated in the same location, garbage data that may or may not be identical to a normal object, or an unmapped memory page that will result in an immediate EXEC_BAD_ACCESS.
Any time you are holding a reference to an object you might use in the future you must retain it. If you don't you have not shown any interest or ownership in the object and the system may throw it away at any time.
Using objective C accessors and properties instead of directly setting ivars and using retain/release simplifies doing the right thing quite a bit.
Multi-threaded programming is hard. Hard does not begin to capture how difficult it is. This is the kind of hard in which a general, useable, 'reasonably qualified' way of deterministically adding two different numbers together that are being mutated and shared by multiple threads in bounded time without the use of any special assistance from the CPU in the form of atomic instructions would be a major breakthrough and the thesis of your PhD. A deity of your choice would publicly thank you for your contribution to humanity. Just for adding two numbers together. Actually, multi-threaded programming is even harder than that.
Take a look at: Technical Note TN2059
Using collection classes safely with multithreaded applications. It covers this topic in general, and outlines some of the non-obvious pitfalls that await you.
You say
I need the other thread to check either its existence or validity before acting on it.
The easiest way is to hold on to the index of the object in the NSMutableArray and then do the following
if( myObject == [myArray objectAtIndex: myObjectIndex] ) {
// everything is good !
}
else {
// my object is not what I think it is anymore
}
There are clear problem with this approach however
insertion, and deletion will stuff you up
The approach is not thread safe since the array can be changed while you are reading it
I really recomend using a different way to share this array between the two threads. Does it have to be mutable? If it doesn't then make it immutable and then you no longer have to worry about the threading issues.
If it does, then you really have to reconsider your approach. Hopefully someone can give an cocoa way of doing this in a thread safe way as I don't have the experience.