Cocoa Streams
Streams provide an easy way for a program to exchange data with a variety of media in a device-independent way. A stream is a contiguous sequence of bits transmitted serially over a communications path. It is unidirectional and hence, from the perspective of a program, a stream can be an input (or read) stream or an output (or write) stream. Except for file-based streams, streams are non-seekable—once stream data has been provided or consumed, it cannot be retrieved again from the stream.
Cocoa includes three stream-related classes: NSStream
, NSInputStream
, and NSOutputStream
. NSStream
is an abstract class that defines the fundamental interface and properties for all stream objects. NSInputStream
and NSOutputStream
are subclasses of NSStream
and implement default input-stream and output-stream behavior. You can create NSOutputStream
instances for stream data located in memory or written to a file or C buffer; you can create NSInputStream
instances for stream data read from an NSData
object or a file. You can also have NSInputStream
and NSOutputStream
objects at the end points of a socket-based network connection and you can use stream objects without loading all of the stream data into memory at once. Figure 1 illustrates the types of input-stream and output-stream objects in terms of their sources or destinations.
Because they deal with such a basic computing abstraction (streams), NSStream
and its subclasses are intended for lower-level programming tasks. If there is a higher-level Cocoa API that is more suited for a particular task (for example, NSURL
or NSFileHandle
) use it instead.
Stream objects have properties associated with them. Most properties have to do with network security and configuration, namely secure-socket (SSL) levels and SOCKS proxy information. Two important additional properties are NSStreamDataWrittenToMemoryStreamKey
, which permits retrieval of data written to memory for an output stream, and NSStreamFileCurrentOffsetKey
, which allows you to manipulate the current read or write position in file-based streams.
A stream object also has a delegate associated with it. If a delegate is not explicitly set, the stream object itself becomes the delegate (a useful convention for custom subclasses). A stream object invokes the sole delegation method stream:handleEvent:
for each stream-related event it handles. Of particular importance are the events that indicate when bytes are available to read from an input stream and when an output stream signals that it’s ready to accept bytes. For these two events, the delegate sends the stream the appropriate message—read:maxLength:
or write:maxlength:
, depending on type of stream—to get the bytes from the stream or to put bytes on the stream.
NSStream
is built on the CFStream
layer of Core Foundation. This close relationship means that the concrete subclasses of NSStream
, NSOutputStream
and NSInputStream
, are toll-free bridged with their Core Foundation counterparts CFWriteStream
and CFReadStream
. Although there are strong similarities between the Cocoa and Core Foundation stream APIs, their implementations are not exactly coincident. The Cocoa stream classes use the delegation model for asynchronous behavior (assuming run-loop scheduling) while Core Foundation uses client callbacks. The Core Foundation stream types sets the client (termed a context in Core Foundation) differently than the NSStream sets the delegate; calls to set the delegate should not be mixed with calls to set the context. Otherwise you can freely intermix calls from the two APIs in your code.
Despite their strong similarities, NSStream
does give you a major advantage over CFStream
. Because of its Objective-C underpinnings, it is extensible. You can subclass NSStream
, NSInputStream
, or NSOutputStream
to customize stream attributes and behavior. For example, you could create an input stream that maintains statistics on the bytes it reads; or you could make a NSStream
subclass whose instances can seek through their stream, putting back bytes that have been read. NSStream
has its own set of required overrides, as do NSInputStream
and NSOutputStream
. See the reference documentation for NSStream
, NSInputStream
, and NSOutputStream
for details on subclassing these classes.
Copyright © 2004, 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-12-16