Using some of Cocoa’s existing design patterns is one of the most effective ways to help developers develop applications with sound design ideas, stable performance, and good scalability. These patterns all depend on classes defined in Objective-C. Because of Swift’s interoperability with Objective-C, you can still use these design patterns in Swift code. In some cases, you can even extend or simplify these Cocoa design patterns using features of the Swift language to make them more powerful and easier to use.

Delegation

In Swift and Objective-C, delegates are typically represented by a protocol that defines interactive methods and delegate properties that follow the specification. Compared to Objective-C, when you inherit a delegate in Swift, the inheritance pattern stays the same, but the internal implementation has changed. Just like in Objective-C, before you send a message to a delegate, whether it’s nil or not you’re going to look at it, and if you define a method that doesn’t have to be implemented, you’re going to look at it whether the delegate implements it or not. In Swift, these tedious and unnecessary behavior problems can be effectively eliminated by maintaining type safety.

The code listed below illustrates this process:

  1. Check that myDelegate is not nil.
  2. Check whether myDelegate implementation window: inherited willUseFullScreenContentSize: method.
  3. If myDelegate is nil and realized the window: willUseFullScreenContentSize: method, so this method is invoked, assign the return value of this method is called fullScreenSize properties.
  4. Output the return value of the method to the console.

As a developer, it is particularly important to have a learning atmosphere and a communication circle. This is my iOS development public number: Programming Daxin, whether you are small white or big ox are welcome to enter. Let us progress together and develop together! (The group will provide some free study books collected by the group owner and hundreds of interview questions and answers documents for free!) 支那

1. // @inteface MyObject : NSObject 2. // @property (nonatomic, weak) id<NSWindowDelegate> delegate; 3. // @end 4. if let fullScreenSize = myDelegate? .window? (myWindow, willUseFullScreenContentSize: mySize) { 5. println(NSStringFromSize(fullScreenSize)) 6. }Copy the code

Note: In an app written entirely in Swift, the delegate property is defined as an undefined NSWindowDelegate object with an initial value set to nil.

Lazy Initialization

You can learn more about Lazy initialization in Lazy Stored Properties.

Error Reporting

The error reporting pattern in Swift follows the Objective-C pattern, but the new feature of undefined return values in Swift gives us an additional benefit. For a very simple example, if you use a Bool as the return value of a function to indicate whether the function was successfully executed, you can add an output parameter of type NSErrorPointer, NSError, to the function when you need to output an error message. This type is similar to NSError ** in Objective-C, with added memory safety and non-mandatory pass-through. You can use the & operator as a prefix to reference an undefined NSError type as an NSErrorPointer object to pass an error message. The following code looks like this:

1. var writeError : NSError? 2. let written = myString.writeToFile(path, atomically: false, 3. encoding: NSUTF8StringEncoding, 4. error: &writeError) 5. if ! written { 6. if let error = writeError { 7. println("write failure: \(error.localizedDescription)") 8. } 9. }Copy the code

When you implement your method, you need to configure an NSErrorPointer object and set the Memory property of the NSErrorPointer object to the NSError object you created. First check the argument passed by the caller to make sure it is a non-nil NSError object.

1. func contentsForType(typeName: String! error: NSErrorPointer) -> AnyObject! { 2. if cannotProduceContentsForType(typeName) { 3. if error { 4. error.memory = NSError(domain: domain, code: code, userInfo: [:]) 5. } 6. return nil 7. } 8. // ... 9.}Copy the code

Target-action mode (target-Action)

When certain events occur that require one object to send a message to another, we usually use the Target-Action design pattern of Cocoa. Swift is basically similar to the target-action model in Objective-C. In Swift, you can use the Selector type to achieve the effect of selectors in Objective-C. See objective-C Selectors for examples of using the target-Action design pattern in Swift.

Type Matching and Unified Specification (Introspection)

In Objective-C, you can use the isKindOfClass: method to check whether an object is of a specified type, and the conformsToProtocol: method to check whether an object complies with the specifications of a particular protocol. In Swift, you can do this using the IS operator, or you can use as? Matches down to the specified type.

You can use the IS operator to check whether an instance is a specified subclass. The result of is is true if the instance is a specified subclass, false otherwise.

1.  if object is UIButton {
2.  // object is of type UIButton
3.  } else {
4.  // object is not of type UIButton
5.  }
Copy the code

You can also use as? Operator tries to match down subtypes, as? Operator returns an indefinite value, used in conjunction with if-let statements.

1.  if let button = object as? UIButton {
2.  // object is successfully cast to type UIButton and bound to button
3.  } else {
4.  // object could not be cast to type UIButton
5.  }
Copy the code

Check out Type Casting for more information.

The syntax for checking the matching protocol is the same as that for checking the matching class. Example of checking a matching protocol:

1.  if let dataSource = object as? UITableViewDataSource {
2.  // object conforms to UITableViewDataSource and is bound to dataSource
3.  } else {
4.  // object not conform to UITableViewDataSource
5.  }
Copy the code

Note that the dataSource is converted to a UITableViewDataSource type after the match, so you can only access and call properties and methods defined by the UITableViewDataSource protocol. When you want to do something else, you have to convert it to something else.

You can view more information from Protocols.