0

I have view that displays an image in the background. The image is picked from an array of images and I am using a random function to pick them. On doing so the app crashes but ONLY on an iPhone 5/5S.

Here is my code: ...

//Images
let rest28 = UIImage(named: "rest28")
        let rest29 = UIImage(named: "rest29")
        let rest30 = UIImage(named: "rest30")

// image Array
        imageArray = [rest1!, rest3!, rest4!, rest5!, rest6!, rest7!, rest8!, rest9!,
            rest10!, rest11!, rest12!, rest13!, rest15!, rest17!, rest18!, rest21!, rest22!, rest24!, rest25!, rest26!, rest27!, rest28!, rest29!, rest30!]

        // Picking a number in the array of images. 
        let randomImageSelection = 0 + Int(arc4random()) % (0 - imageArray.count - 1)
        backgroundImage.image = imageArray[randomImageSelection]

This is the crash I get on the randomImageSelection function:

- Failed to set (isHomeScreenImage) user defined inspected property on (UIView): [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key isHomeScreenImage.

enter image description here

Thanks for the help in advance. :)

Gugulethu
  • 1,426
  • 3
  • 18
  • 36
  • remove this lines, and try again, is still crashing? Your error doesn't appear to be related with this – Hugo Alonso Feb 17 '16 at 16:52
  • It is pointless to set the view's layer's `masksToBounds` and its `clipsToBounds`, as they are identically the same thing. – matt Feb 17 '16 at 16:52
  • I agree with @HugoAlonso. You need to ask yourself where this `isHomeScreenImage` is coming from, since it has nothing to do with the code you are showing. – matt Feb 17 '16 at 16:53

1 Answers1

3

arc4random() yields an unsigned 32-bit integer (UInt32). The standard Int corresponds to 32-bit (signed) integer on iPhone 5 (iPhone 5 - 1.3 GHz dual core 32-bit ARMv7-A processor), Int32 type, in which case Int(arc4random()) will yield a(n) (integer overflow) runtime exception ~50% of the time the line above runs, on average. Why? Half of the numbers representable by UInt32 type are too large to be represented by the Int32 type.

print(INT32_MAX)  // 2147483647
print(UINT32_MAX) // 4294967295 <-- max return of arc4random()

There is really no need for you to generate any random number in the range of a 32-bit unsigned integer using the arc4random() function; an alternative is using arc4random_uniform() to generate a random number in the range 0..<30. Try replacing the line you've marked for error with the following:

let randomImageSelection = arc4random_uniform(UInt32(imageArray.count))
    /* random Integer in: 0 ..< imageArray.count */

Closely related thread (to which this is possible a duplicate), thanks @Eric D.

Community
  • 1
  • 1
dfrib
  • 70,367
  • 12
  • 127
  • 192
  • @HugoAlonso Since the compiler can't know at compile time that `arc4random` will return a number that is too large to store in `Int32` (integer overflows). Hence, the code will compile but yield a runtime exception when trying to initialize an `Int32` with an integer that is too large. Try `let foo = Int8(arc4random())` in a playground yourself, and you should see the same behaviour. – dfrib Feb 17 '16 at 17:08
  • yes, but, what about "this class is not key value coding-compliant for the key isHomeScreenImage"? This appears to be just part of the problem, but or there's something more happening here or the debugger is not throwing the correct error description. – Hugo Alonso Feb 17 '16 at 17:15
  • @HugoAlonso To be honest I missed that completely (no excuse), I simply looked at the screenshot of the runtime exception. Anyway, the op should fix the integer overflow issues and see if the 2nd error persists. Could be that the other error follows from the runtime exception. – dfrib Feb 17 '16 at 17:17
  • 1
    @EricD. You're right, that looks like the same issue. I guess in that thread the specific issue is using `NSEC_PER_SEC` (`=1000000000`) multiplied with, at most, `3`, yielding `3000000000 > 2147483647 = INT32_MAX`. The issue above is the same integer overflow issue, but here stemming from the another computation: max return of `arc4random()`, which is `4294967295 > 2147483647`. Should we mark this one as a duplicate? (After seeing if this answer fixes also the other error, _"this class is not key value ..."_). – dfrib Feb 17 '16 at 17:20