aboutsummaryrefslogtreecommitdiffhomepage
path: root/objectivec/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'objectivec/README.md')
-rw-r--r--objectivec/README.md93
1 files changed, 84 insertions, 9 deletions
diff --git a/objectivec/README.md b/objectivec/README.md
index 186e45b2..134bf1ab 100644
--- a/objectivec/README.md
+++ b/objectivec/README.md
@@ -21,15 +21,15 @@ Installation
------------
The full distribution pulled from github includes the sources for both the
-compiler (protoc) and the runtime (this directory). To build the compiler
+compiler (protoc) and the runtime (this directory). To build the compiler
and run the runtime tests, you can use:
$ objectivec/DevTools/full_mac_build.sh
This will generate the `src/protoc` binary.
-Usage
------
+Building
+--------
There are two ways to include the Runtime sources in your project:
@@ -47,6 +47,80 @@ If the target is using ARC, remember to turn off ARC (`-fno-objc-arc`) for the
The files generated by `protoc` for the `*.proto` files (`\*.pbobjc.h' and
`\*.pbobjc.m`) are then also added to the target.
+Usage
+-----
+
+The objects generated for messages should work like any other Objective C
+object. They are mutable objects, but if you don't change them, they are safe
+to share between threads (similar to passing an NSMutableDictionary between
+threads/queues; as long as no one mutates it, things are fine).
+
+There are a few behaviors worth calling out:
+
+A property that is type NSString\* will never return nil. If the value is
+unset, it will return an empty string (@""). This is inpart to align things
+with the Protocol Buffers spec which says the default for strings is an empty
+string, but also so you can always safely pass them to isEqual:/compare:, etc.
+and have deterministic results.
+
+A property that is type NSData\* also won't return nil, it will return an empty
+data ([NSData data]). The reasoning is the same as for NSString not returning
+nil.
+
+A property that is another GPBMessage class also will not return nil. If the
+field wasn't already set, you will get a instance of the correct class. This
+instance will be a temporary instance unless you mutate it, at which point it
+will be attached to its parent object. We call this pattern *autocreators*.
+Similar to NSString and NSData properties it makes things a little safer when
+using them with isEqual:/etc.; but more importantly, this allows you to write
+code that uses Objective C's property dot notation to walk into nested objects
+and access and/or assign things without having to check that they are not nil
+and create them each step along the way. You can write this:
+
+```
+- (void)updateRecord:(MyMessage *)msg {
+ ...
+ // Note: You don't have to check subMessage and otherMessage for nil and
+ // alloc/init/assign them back along the way.
+ msg.subMessage.otherMessage.lastName = @"Smith";
+ ...
+}
+```
+
+If you want to check if a GPBMessage property is present, there is always as
+`has\[NAME\]` property to go with the main property to check if it is set.
+
+A property that is of an Array or Dictionary type also provides *autocreator*
+behavior and will never return nil. This provides all the same benefits you
+see for the message properties. Again, you can write:
+
+```
+- (void)updateRecord:(MyMessage *)msg {
+ ...
+ // Note: Just like above, you don't have to check subMessage and otherMessage
+ // for nil and alloc/init/assign them back along the way. You also don't have
+ // to create the siblingsArray, you can safely just append to it.
+ [msg.subMessage.otherMessage.siblingsArray addObject:@"Pat"];
+ ...
+}
+```
+
+If you are inspecting a message you got from some other place (server, disk,
+etc), you may want to check if the Array or Dictionary has entries without
+causing it to be created for you. For this, there is always a `\[NAME\]_Count`
+property also provided that can return zero or the real count, but won't trigger
+the creation.
+
+For primitive type fields (ints, floats, bools, enum) in messages defined in a
+`.proto` file that use *proto2* syntax there are conceptual differences between
+having an *explicit* and *default* value. You can always get the value of the
+property. In the case that it hasn't been set you will get the default. In
+cases where you need to know whether it was set explicitly or you are just
+getting the default, you can use the `has\[NAME\]` property. If the value has
+been set, and you want to clear it, you can set the `has\[NAME\]` to `NO`.
+*proto3* syntax messages do away with this concept, thus the default values are
+never included when the message is encoded.
+
The Objective C classes/enums can be used from Swift code.
Objective C Generator Options
@@ -55,18 +129,19 @@ Objective C Generator Options
**objc_class_prefix=\<prefix\>** (no default)
Since Objective C uses a global namespace for all of its classes, there can
-be collisions. This option provides a prefix that will be added to the Enums
-and Objects (for messages) generated from the proto. Convention is to base
+be collisions. This option provides a prefix that will be added to the Enums
+and Objects (for messages) generated from the proto. Convention is to base
the prefix on the package the proto is in.
Contributing
------------
Please make updates to the tests along with changes. If just changing the
-runtime, the Xcode projects can be used to build and run tests. If change also
-require changes to the generated code, `objectivec/DevTools/full_mac_build.sh`
-can be used to easily rebuild and test changes. Passing `-h` to the script will
-show the addition options that could be useful.
+runtime, the Xcode projects can be used to build and run tests. If your change
+also requires changes to the generated code,
+`objectivec/DevTools/full_mac_build.sh` can be used to easily rebuild and test
+changes. Passing `-h` to the script will show the addition options that could
+be useful.
Documentation
-------------