I am using this line of code
let transactions = SKPaymentQueue.default().transactions
This is what Apple amazing docs has to say about transactions.
What is exactly "undefined"? How do I test transactions before proceeding in code?
I have an observed attached to the payment queue.
I can guarantee you that undefined is not nil, because I have tested for nil and Xcode whined with an error
Comparing non-optional value of type '[SKPaymentTransaction]' to 'nil' always returns false
is undefined the new "empty array"? If not, how do I test for that?
Undefined means literally that: the API does not define what the framework will do. Anything is "fair game".
The code might cause a fatal error, return an empty array, or trigger a workflow to send a postcard to you in the mail. It's not defined.
However, no matter what the current behaviour happens to be, you shouldn't depend on it. It might return an empty array today, but crash tomorrow. Because the API explicitly documents the behaviour as undefined, Apple is free to change implementation details, without them counting as "API breaking changes".
Related
I get the following error in XCode...
I've added a "Swift Error" breakpoint and left the "Type" box empty. I thought this might show some further info, but it doesn't appear to have any effect.
How can I find out where this error is arising from?
EXC_BAD_INSTRUCTION means that you have an invalid assertion (usually a force-unwrapped nil, though a bad cast could also be the culprit, here). Make sure that tourDto is a populated var, and that it can be cast to whatever toJSONString() returns (I'm not familiar with that method, and it could also be the culprit).
In swift I declared a variable as
let context:LAContext = LAContext()
It throws a warning
"Initialisation of immutable value'context' was never used, consider replacing assignment to '_' or removing it.
It's all in the error message
value...was never used
Your variable isn't being used anywhere, so Xcode tells you that you can remove it (because having unused variables is a waste of memory). Just use your variable somewhere and the error will go away (e.g. get a value from it, print it, etc).
Of course you mean to use it somewhere right? Otherwise you wouldn't have declared it. It's just that the Xcode (especially the new one, I noticed) checks for errors immediately, so these kinds of errors appear before you can really do anything about it.
Edit: I didn't imagine that almost 7 years later people would still be commenting on a post regarding a beginner-level compiler warning, but to be more specific, yes there are some cases where you might not want to keep a variable around or where you want to discard some return value, so you don't necessarily always "mean to use it somewhere". See comments for more.
My Swift application running in iOS simulator is being stopped in debugger with runtime error EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, sub code=0x0).
According to the WWDC 2014 Session 409 this is typically due to assertion failure.
In the current development Beta version of Xcode 6, the debugger’s stack trace and the above error does not provide enough information to see what the issue is. How do I find out where the problem is?
It appears that the most common source of this error (at the time of this writing: Xcode 6 Beta 1) is that some implicitly unwrapped optional property or variable is nil.
For convenience, most Objective-C API are bridged to Swift with implicitly unwrapped optionals. They are denoted by exclamation mark behind the type declaration: AnyObject[]!
If the debugger stops in your code, double-check that line and look for implicitly unwrapped optionals that could be nil there.
Sometimes the debugger stops with that runtime error deep in Swift system library. This happens for example when you pass a closure to collection methods like filter, map, reduce et al. The runtime error then occurs at the call site of those library functions, but the definition might be in different parts of your code, where you defined the function/closure. Look there for implicitly unwrapped optionals that might be nil at runtime.
To guard agains these kinds of error be aware that even though Swift compiler will not force you to handle the potential nil values returned from Cocoa, you should use optional binding, optional chaining
or optional downcasting wherever the return value from Objective-C land might be nil.
Let’s hope that future versions of Swift compiler will start emitting more helpful diagnostic messages and errors for this common type of problem!
I have found (after many hours) that this error can appear on the wrong line.
For example
As you can see the app is crashing where I am checking for nil, but then 'continuing' through because it prints the statements. It then goes 'backwards' and crashes.
I've come to the conclusion that there is a source-mapping bug in XCode (7) where a nil variable is un-wrapped. In this case, I had a variable (much farther down in my code) that was nil and being unwrapped.
The problem of course is that the compiler didn't flag the actual variable that was nil, it flagged something else entirely.
So if you run into this nasty bug, go through all possible variables that can be nil and check them for unwrapping. You are likely unwrapping a nil, its just not the one the compiler says.
As mentioned in the comment there is compiler optimization. Here is a link to fix the issue (and find the route cause of the crash)
xcode 6.1 how to disable optimization (Swift)
I had the same issue as Palimondo. Fortunately, it was simply a matter of making sure that I had initialized the item ahead of time. In my code, I was calling a function to place images in UIImageViews and passing in an element from an array. I had not yet loaded my array with the UIImageViews, and therefore when the code would run it would say that I was passing in a nonexistent element of the array. Once I made sure to load up my array at the start of the program the error went away.
I have an app submitted to Apple Store, and it passed. But I found there was a bug will make the app crash. Finally, I found the real problem is a snap of code has the opposite result.
code:
CGPoint now;
CGPoint old;
UIView *lastDot;
now = dotView.center;
if(lastDot){
//release version, will go here. then crashed.
old = lastDot.center;
}else{
//debug version, will go here. run ok.
}
I declare a UIView pointer, and check it with "if statement",
UIView *lastDot;
the debug version consider the lastDot as nil, but the release version think is not null.
can anyone give me any idea? thank you.
Depending on your compiler settings, debug builds usually initialize pointers to some sentinel values like 0xcccccccc.
UIView *lastDot = nil;
Should work as expected.
The issue is due to uninitialized pointer.
Initialize it to nil for avoiding such troubles.
UIView *lastDot = nil;
I know you already got the answer.
I just want to add some points too:
Pointers are just like any other variable: if you don't explicitly set
them to a value, the value will be undefined means a random value. If
you then accidentally access the variable, very bad things can happen.
Sometimes people recommend that pointers be assigned to NULL, the
universal value meaning "this pointer doesn't point at anything",
because a lot of code already checks for NULL pointers. For example,
if you call [nil release], it's guaranteed to do nothing. If you
passed an uninitialized pointer in who knows what would happen.
It's really just a safeguard against programmer error. If you
initialize pointers to a reasonable value, it's less likely that an
uninitialized pointer will cause a system crash sometime in the
future.
When you don't initialize a pointer and then try to use it, you have 3
problems:
It might be pointing at memory you don't have access to, in which case it causes a segmentation fault and crashes your program
It might be pointing at real data, and if you don't know what it's pointing to, you're causing unpredictable (and very hard to debug)
changes to your data.
You have no way of knowing if it's been initialized or not - because how do you tell the difference between a valid address and the address
that happened to be there when you declared the pointer?
Initializing every pointer to nil seriously decreases or eliminates
those problems:
If I try and use it, it will still segfault, but at least I can test if it's NULL and act accordingly - I can know that it WILL segfault,
and do something else. If it's a random value, I don't know anything
until it crashes.
If you initialize it to nil, I can't make it point to data unless I explicitly tell it to. So I only modify what I meant to.
As implied above, I can tell when I've initialized it and when I haven't, and make a decision.
Obviously it's a matter of style, and it is possible to write an
application where variables are only initialized to their intended
value, but I feel it is safer and easier to initialize them to nil
always. Even the best programmers make typos - nil makes it easier
to know when that's happened.
Reference :
eskimo
Initializing pointers always necessary
Error: sqlite3_finalize failed (database is locked). I have released memory also properly in each view. Has anyone faced this issue?
I think you're hitting some legacy cruft in the SQLite interface. To summarize, when you sqlite3_step and the result is an error, slite3_finalize will return the same error. Pay attention to the error from sqlite3_step and other SQLite calls, and ignore the error from slite3_finalize.
Per SQLite documentation for sqlite3_finalize:
If the most recent evaluation of the statement encountered no errors or or if the statement is never been evaluated, then sqlite3_finalize() returns SQLITE_OK. If the most recent evaluation of statement S failed, then sqlite3_finalize(S) returns the appropriate error code or extended error code.
It talks about the most recent evaluation of the statement rather than the finalize itself. This is nowhere near explicit enough, but there's another comment in the documentation that is:
Goofy Interface Alert: In the legacy interface, the sqlite3_step() API always returns a generic error code, SQLITE_ERROR, following any error other than SQLITE_BUSY and SQLITE_MISUSE. You must call sqlite3_reset() or sqlite3_finalize() in order to find one of the specific error codes that better describes the error.
It goes on to say this is fixed by the v2 APIs, but I think that's only partially correct. When using the v2 APIs, sqlite3_step returns an error code directly. However, there's no sqlite3_finalize_v2. And in my testing, sqlite3_finalize continues to return the error code from sqlite3_step.
In other words: Ignore the error from sqlite3_finalize. Pay attention to the error you're almost certainly getting but ignoring from sqlite3_step.
"Database is locked" means that (duh!) the database is locked. Some other sqlite operation against the database is still "pending", possibly because you failed to finalize an earlier query, or possibly because there's a query going on in an async thread.