Where to store AppConstants and User Strings without affecting Memory

Swift 4.2 still doesn't provide an ideal way to store App Constants and User Strings without affecting memory or I still haven't figured out a way to do it effectively.

final class UserStrings {
    /// contains the user strings for Pro Info Cell in Pros Module.
    enum MovieCell: String {
        case referencesAvailable = "References Available"
        case rating = "Rating:"
        case ratingCount = "rating(s)"
    }

    enum MovieDetails: String {
        case servicesNotAvailable1 = "Services Not Available1"
        case servicesNotAvailable2 = "Services Not Available2"
        case servicesNotAvailable3 = "Services Not Available3"
        case servicesNotAvailable4 = "Services Not Available4"
        case servicesNotAvailable5 = "Services Not Available5"
    }
}

and

final class HAUserStrings {
    /// contains the user strings for Pro Info Cell in Pros Module.
        static let referencesAvailable = "References Available"
        static let rating = "Rating:"
        static let ratingCount = "rating(s)"
        
        static let servicesNotAvailable = "Services Not Available"
}

Above two approaches will load the strings into Stack even the App might not need them. For example, User launch the app and login screen is displayed. At that time user needs the user string for only that screen and app doesn't need to load all the strings required for the entire app.

Please share your thoughts on how Swift5 should improve the App Constants and User Strings?

What's your use case? Why is this a problem for you? Have you profiled the memory usage of your app?

1 Like

I guess you don't care about localization. iOS has NSLocalizedString() for this purpose, although I assume the strings files are loaded into memory all at once.

There is a more general question of how to do application constants that is related to this.

What is it thr you‘re pitching? It seems to me this is the wrong category, I think it should go into #swift-users.

final class HAUserStrings {
    /// contains the user strings for Pro Info Cell in Pros Module.
        static let referencesAvailable = "References Available"
        static let rating = "Rating:"
        static let ratingCount = "rating(s)"
        
        static let servicesNotAvailable = "Services Not Available"
        .... 10 thousand more constants ....
        static let servicesIsAvailable = "Services is now Available"
}

Think about a constant file with 10 thousand or more AppConstants and other string values.

Now when this file is loaded into the memory, all these constants will be loaded into the memory. Even though App might not need them. So it definitely takes up unnecessary memory.

Please share your thoughts on how we can avoid this in upcoming Swift versions.

Once you have a compiled and linked executable, you shouldn't think about your program in terms of individual source files; i.e., "when this file is loaded into the memory" isn't what you're going to have happen under the hood.

Instead, the text of the string literals defined throughout your code will be stored in a special read-only section of the binary. The executable is memory-mapped into the process's address space such that the pages containing the strings will only be loaded when your program accesses those pages. If your strings are so large that they span multiple pages, only the pages being accessed will be loaded into memory. If the OS needs that space for something else and the page(s) containing your strings haven't been used in a while, then it can purge those pages from memory.

Furthermore, static and global variables in Swift are lazily loaded, so the String instances corresponding to those variables won't actually be allocated and initialized (and thus their pages loaded) until your program first accesses them.

That being said, if you're targeting an Apple platform and you have a large amount of strings, you might want to consider moving them to a .strings resource file instead. As mentioned above, that will make localization easier.

16 Likes

@allevato Is there any documentation on this? I'm looking everywhere to find more documentation on it. Can you please send the link if you could find them. Thanks!

Apple's documentation has a lot of discussion about the virtual memory system here, and this post on the official Swift blog talks about the initialization of global/static variables.

2 Likes