Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
F

FastCoding

> 编程语言
Open source

A faster and more flexible binary file format replacement for NSCoding, Property Lists and JSON

979 stars0 likes0 views
WebsiteGitHub

About

A faster and more flexible binary file format replacement for NSCoding, Property Lists and JSON

Purpose

FastCoder is a high-performance binary serialization format for Cocoa objects and object graphs. It is intended as a replacement for NSPropertyList, NSJSONSerializer, NSKeyedArchiver/Unarchiver and Core Data.

The design goals of the FastCoder library are to be fast, flexible and secure.

FastCoder is already faster (on average) for reading than any of the built-in serialization mechanisms in Cocoa, and is faster for writing than any mechanism except for JSON (which doesn't support arbitrary object types). File size is smaller than NSKeyedArchiver, and comparable to the other methods.

FastCoder supports more data types than either JSON or Plist coding (including NSURL, NSValue, NSSet and NSOrderedSet), and allows all supported object types to be used as the keys in a dictionary, not just strings.

FastCoder can also serialize your custom classes automatically using property inspection. For cases where this doesn't work automatically, you can easily implement your own serialization using the FastCoding or NSCoding protocols.

Supported OS & SDK Versions

  • Supported build target - iOS 11.0 / Mac OS 10.12 (Xcode 9.2)
  • Earliest supported deployment target - iOS 9.0 / Mac OS 10.10
  • Earliest compatible deployment target - iOS 4.0 / Mac OS 10.6

NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this OS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.

ARC Compatibility

FastCoder is compatible with both ARC and non-ARC compile targets, however, performance is better when running with ARC disabled, and it is recommended that you apply the -fno-objc-arc compiler flag to the FastCoder.m class. To do this, go to the Build Phases tab in your target settings, open the Compile Sources group, double-click FastCoder.m in the list and type -fno-objc-arc into the popover.

Thread Safety

It is safe to call the FastCoder encoding and decoding class methods concurrently from multiple threads. It should also be safe to encode the same object concurrently on multiple threads provided that you do not mutate the object while it is being encoded.

Installation

To use FastCoder, just drag the FastCoder.h and .m files into your project.

Security

The FastCoding parser checks for buffer overflow errors whilst parsing, and will throw an exception if the data instructs it to try to read past the end of the data file. This should prevent most kinds of code injection attack.

Whilst it is not possible to use a FastCoded file to inject code, as with NSCoding, an attacker could use a modified FastCoded file to cause unexpected classes to be created in your object graph, which might present a potential attack risk (note that only classes that already exist in your code base or a built-in Cocoa Framework can be created this way).

For the time being, it is best not to try to load arbitrary FastCoded files from an untrusted source (although it is fine to use them for saving data internally within your application's sandbox). If you want to exchange FastCoded files between apps or users, use only the explicitly supported class types (listed below) and load the file using propertyListWithData:, which only supports safe types and will refuse to load a file containing unknown classes. A future release of the FastCoding library will add more sophisticated whitelisting capabilities.

Supported Classes

FastCoding supports the following class types natively:

NSNull
NSNumber
NSDecimalNumber
NSValue (only the following subtypes)
    CGPoint/NSPoint
    CGSize/NSSize
    CGRect/NSRect
    CGVector
    NSRange
    CGAffineTransform
    CATransform3D
NSString
NSMutableString
NSArray
NSMutableArray
NSDictionary
NSMutableDictionary
NSSet
NSMutableSet
NSOrderedSet
NSMutableOrderedSet
NSIndexSet
NSMutableIndexSet
NSData
NSMutableData
NSDate

FastCoding also automatically supports any class that complies with the NSCoding protocol, or any class whose properties are all KVC-compliant, or that explicity implements the FastCoding protocol.

FastCoder methods

FastCoder implements the following methods:

+ (id)objectWithData:(NSData *)data;

Constructs an object tree from an FastCoded data object and returns it. FastCoder does not currently provide any mechanism for class validation or substitution, so this method should not be used for loading files with unknown provenance (i.e. where you can't guarantee where the file came from, or that the file hasn't been tampered with). For exchanging files between apps, or for user-accessible documents, it is recommended that you use the propertyListWithData: method for loading the file instead (although this does not support arbitrary classes).

If an unknown class type is encountered in the file, it will be loaded as a dictionary of properties that can be converted back into a real class later (see 'Bootstrapping', below). Attempting to load a malformed or corrupt file will throw an exception (caught internally) and return nil.

+ (id)propertyListWithData:(NSData *)data;

Like objectWithData:, but this method is limited to loading "safe" object types such as NSString, NSNumber, NSArray, etc. Despite the name, this method is not actually limited to objects supported by NSPropertyList - for example it supports NSNull and NSURL - however it is safe to use for loading files from untrusted sources. Also, unlike ordinary property list methods, this can handle circular references, aliased objects and mutable containers like NSMutableArray. Attempting to load a malformed or corrupt file, or one containing unsupported classes, will throw an exception (caught internally) and return nil.

+ (NSData *)dataWithRootObject:(id)object;

Archives an object graph as a block of data, which can then be saved to a file or transmitted via a network. The file can be loaded again using objectWithData:, or propertyListWithData: (provided that it only contains supported class types).

The FastCoding Protocol

FastCoding supports encoding/decoding of arbitrary objects using the FastCoding protocol. The FastCoding protocol is an informal protocol, implemented as a category on NSObject. The protocol consists of the following methods:

+ (NSArray *)fastCodingKeys;

This method returns a list of property names that should be encoded/decoded for an object. The default implementation automatically detects all of the non-virtual (i.e. ivar-backed) @properties (including private and read-only properties) of the object and returns them, so in most cases it is not necessary to override this method. NOTE: if you override +fastCodingKeys, you should only include property keys for the current class, not properties that are inherited from the superclass.

- (id)awakeAfterFastCoding;

This method is called after an object has been deserialized using the FastCoding protocol, and all of its properties have been set. The deserialized object will be replaced by the one returned by this method, so you can use this method to either modify or completely replace the object. The default implementation just returns self. NOTE: returning a different object from -awakeAfterFastCoding may lead to unexpected behaviour if the object being decoded (or any of its children) contains a reference to itself.

- (Class)classForFastCoding;

This method is used to supply an alternative class to use for coding/decoding an object. This works the same way as the -classForCoder method of NSCoding, and by default returns the same value.

- (BOOL)preferFastCoding;

Because FastCoding automatically supports NSCoding, any object that conforms to the NSCoding protocol (except for types that are explicitly supported by FastCoding) will be encoded using the NSCoding methods by default. This is better for compatibility purposes, but may be significantly slower than using the FastCoding protocol. If your class supports both NSCoding and FastCoding, and you would prefer FastCoder to use the FastCoding protocol, override this method and return YES (the default value is NO).

- (BOOL)preferKeyedArchiver;

Occasionally you may find that a given class does not work correctly with the FastCoding protocol. Typically this will only be the case for built-in Foundation or UIKit/AppKit classes (the only known case so far is AppKit's NSColorSpace - if you find any others, please report them). In such cases, you can use preferKeyedArchiver to encode these objects using an ordinary NSKeyedArchive embedded within the FastCoded archive. Note that this option has no effect if preferFastCoding is set to YES.

Overriding Default FastCoding Behaviour

If you wish to exclude certain properties of your object from being encoded, you can do so in any of the following ways:

  • Only use an ivar, without declaring a matching @property.
  • Change the name of the ivar to something that is not KVC compliant (i.e. not the same as the property, or the property name with an _ prefix). You can do this using the @synthesize directive, e.g. @synthesize foo = unencodableFoo;
  • Override the +fastCodingKeys method

If you wish to encode additional data that is not represented by an @property, override the +fastCodingKeys method and add the names of your virtual properties. You will need to implement suitable setter/getter methods for these properties, or the encoding/decoding process won't work.

If you wish to substitute a different class for decoding, you can implement the -classForFastCoding method and FastCoding will encode the object as that class instead. If you wish to substitute a different object after decoding, use the -awakeAfterFastCoding method.

If you have removed or renamed a property of a class, and want to provide backward compatibility for a previously saved FastCoder file, you should implement a private setter method for the old property, which you can then map to wherever it should go in the new object structure. E.g. if the old property was called foo, add a private -setFoo: method. Alternatively, override the -setValue:forUndefinedKey: method to gracefully handle any unknown property.

If you want more precise control of the coding, such as using different names for keys, etc. then you can implement the NSCoding protocol. By default, if a class implements NSCoding, FastCoder will rely on the NSCoding methods to encode the object instead of automatically detecting the keys.

Bootstrapping

Sometimes it is useful to be able to define an object graph by hand using a human-readable format such as JSON, but it's tedious and error-prone to write the recursive logic needed to convert the JSON dictionaries to the correct custom objects.

FastCoder has a neat feature that allows you to bootstrap a carefully structured JSON or Plist file into a native object graph via the FastCoding format. To define an object of class Foo using JSON, you would use the following structure:

{
    "$class": "Foo",
    "someProperty1": 1
    "someProperty2": "Hello World!"
}

You could then load this as an ordinary NSDictionary using NSJSONSerialization. But when you then convert this to data using FastCoder, it will detect the $class key and save this using the custom object record format instead of as a dictionary. When the resultant FastCoded data is decoded again, this will be initialized as an object of type Foo instead of a dictionary.

If you attempt to load the FastCoded

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

C

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言