Yes, and in one key way that permeates the structure of Swift to the very foundation.
That difference is optionals.
Swift is a language that makes you be explicit and up-front about the things you have and the things you don't have. This is enforced via optionals.
In Swift, you can't create an instance of a class with uninitialized properties without also declaring that those properties can't be expected to have a value.
So something like this isn't allowed:
It's not allowed because there is no initializer for the RGBColor class that lets someone give the red, green, and blue properties a default value.
But if you add an initializer, you're back in the game because you've given Swift a way to create your entity in a way that gives each property a default value.
This, however, is allowed:
Optionals are sort of like an "IOU." They're a way of saying, "I don't have what you're looking for now, so please give me a pass and let me get it to you later."
That's why this is also allowed:
You can make an instance of RGBColor without setting any of those properties because they are all some sort of optional
! or ? are just two sides of the same coin.
? is a way of saying "this may or may not have a value, so please tread with caution."
! is a way of saying "this doesn't have a value right now (at the moment of class initialization), but I swear it's gonna have a value when you need it. Trust me!
The compiler treats these two entities very differently. With ?, you aren't allowed to reference a value without carefully "unwrapping" it in a way that doesn't assume the value is there.
However, with !, you are telling the compiler to trust that you know what you're doing, so if you try to access that value and it's nil, the app will simply crash. It's your own damn fault too because you said the value was gonna be there.
All of this gets to the core of the cultural difference between Swift and Objective-C. When you have to be explicit about the things you have, might or might not have, and swear you're gonna have, you write your code in fundamentally different ways. By extension you communicate differently and a new culture evolves out of that.
Swift devs really like these compound statements that unwrap all of the optionals in a single stroke, something the new guard command lets you do.
Objective-C devs aren't as explicit about the things they have and don't have, so you have to do some digging to figure out which properties are always going to be populated and which ones might not be.
Generally speaking, Swift builds upon Apple's penchant for writing code that is explicit and up-front about what it does. It takes the concept further by enforcing up-front-ness with respect to the availability of data via optionals.
You can see a similar attitude in Objective-C, which strongly encourages clarity at the call site (another form of being explicit) by forcing you to use external parameter names in your functions. That way, when someone uses your function, they know what they're passing in without guessing or reading documentation.
It's the difference between:
add(leftSide: 1, rightSide:2)
The latter is waaaay more readable. You get what the arguments are for by simply looking at the usage of the function. There's no need to dig into the documentation.
Swift follows a uniquely Apple tradition of improving the developer's experience by making code as clear and concise as possible. To be culturally "Swifty" simply means you care more about these things than the previous generation.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.