A preliminary study of Swift language learning - Mixing Object-C and Swift

A preliminary study of Swift language learning - Mixing Object-C and Swift

After the Swift language comes out, new projects may be developed directly using Swift, but in the process, you may encounter some situations where you don’t want to rewrite some classes or encapsulated modules written in OC in Swift, so you can use mixed compilation. This is allowed in iOS 8.

Let's start with the simple one and study the mixed use in the same project directory.

For demonstration. First prepare two classes

The first one is a class written in Swift, the file name is act.swift

  1. import Foundation
  2.    
  3. class Act : NSObject
  4. {
  5. func hasAct(tag:Int) -> String
  6. {
  7. switch (tag)
  8. {
  9. case   1 : return   "Movie"    
  10. case   2 : return   "CCTV"    
  11. case   3 : return   "Sport TV"    
  12. default : return   "Area TV"    
  13. }
  14. }
  15.        
  16. init()
  17. {
  18. println( "act constructor is called." )
  19. }
  20.        
  21. deinit
  22. {
  23. println( "act destroyed is called." )
  24. }
  25. }

The second one is written in OC. The class header file is OCChannel.h and the implementation file is OCChannel.m

Header Files

  1. # import <Foundation/Foundation.h>
  2.    
  3. @interface OCChannel : NSObject
  4.    
  5. @property (nonatomic,retain) NSString *ChannelName;
  6.    
  7. - (NSString *)ChannelChange:(NSInteger) channels;
  8.    
  9. @end    

Implementation Files

  1. # import   "OCChannel.h"  
  2. # import   "SwiftModule-swift.h"  
  3.  
  4. @interface OCChannel()
  5. {
  6. Act *act; //Swift class  
  7. }
  8. @end  
  9.  
  10. @implementation OCChannel
  11.  
  12. - (id)init
  13. {
  14. if (self = [ super init]) {
  15. NSLog(@ "OC Constructor is called." );
  16. //Using Swift class  
  17. act = [[Act alloc]init];
  18. }
  19. return self;
  20. }
  21.  
  22. - ( void )dealloc
  23. {
  24. NSLog(@ "OC Destroyed is called." );
  25. //[act release];//ARC not used  
  26. //[super dealloc];//ARC not use  
  27. }
  28.  
  29. - (NSString *)ChannelChange:(NSInteger) channels
  30. {
  31. return [act hasAct:channels];
  32. }
  33.  
  34. @end   

This OCChannel references the Act class written in Swift. It is mainly to demonstrate that in the same project, the Swift class calls OC, and the OC class also calls Swift, thus forming a mixed writing mode.

Here are the specific steps:

1. Create a new Swift project: My project is called MixDemo

After the project is completed:

2. Import the two previous classes separately. Let's do it one by one. Because we are building Swift, let's first mix and compile by referencing the OC file in the Swift project.

Using OC in Swift

First of all, Swift no longer uses header files and .m files. So there is no need to use import "" to import header files. How can Swift access OC class declarations?

In fact, Swift also needs to use header files for access, but it no longer needs to be imported explicitly. There are two ways to generate this header file.

Method 1: In a brand new Swift, use the first new creation prompt to automatically add a bridging header file.

After clicking OK, a header file named <produceName-Bridging-Header.h> will be generated.

The completed project:

One thing you need to pay attention to here is to set the bridging header file in targets->build settings->Object-C Bridging Header.

After the above steps, the bridging file is ready.

Feel free to put the Objective-C header files you want to call in your Swift class into this bridge file using import "". Like:

  1. //  
  2. // Use this file to import your target's public headers that you would like to expose to Swift.  
  3. //MixDemo/MixDemo-Bridging-Header.h  
  4.    
  5. # import   "OCChannel.h"    

Similarly, once you know the relationship between Swift search header files, you don't need to care about the -Bridging-Header.h file anymore. You can create one manually and give it a name you like. For example:

Method 2:

Create a new header file named: OCContainerHeader.h

OK, the above settings fully satisfy the classes written in Swift using OC.

  1. import UIKit
  2.  
  3. class ViewController: UIViewController {
  4.  
  5. override func viewDidLoad() {
  6. super .viewDidLoad()
  7. // Do any additional setup after loading the view, typically from a nib.  
  8.  
  9. //Call OC class  
  10. var channel = OCChannel()
  11. println(channel.ChannelChange( 10 ))
  12. println(channel.ChannelChange( 2 ))
  13. }
  14.  
  15. override func didReceiveMemoryWarning() {
  16. super .didReceiveMemoryWarning()
  17. // Dispose of any resources that can be recreated.  
  18. }
  19.  
  20.  
  21. }

Now let's take a look at how OC calls a class written in Swift. (In fact, if you copied my DEMO exactly, then congratulations, you will not be able to compile the above. Because my OC class references a class written in Swift, so if you want to run it, you must comment the class of that Act.)

How to call a class written in Swift in OC

To use OC, you must have a header file. But Swift files do not have header files, so we must also generate a header file. But the header file for OC to call Swift is quite special. Because the mechanism in the header file is automatically generated, it is not recommended to write it by hand if you are not familiar with it.

How to generate this header file. (Note that the header file set by the system cannot be seen in the project.)

Generation steps:

Select targets->build settings->packing->Product Module Name and set the module name. This name is very important. The Swift header file is named according to this.

In this way, if you want to use OC in Swift in your project, you can write all the header files of the OC classes you need to use in MixDemo-Bridging-Header.h. Similarly, if you use the Swift class in OC, you only need to clean it and then compile it, but don't forget to import SwiftModule-swift.h (the name is up to you, but -swift.h is fixed). There is another thing that readers need to pay attention to.

Note:

If a class written in Swift does not inherit from NSObject or a derived class of NSObject, the corresponding conversion class will not be generated after compilation, so that the corresponding declaration cannot be found in OC.

For example, class Act in my example will not be compiled into SwiftModule-swift.h, but if it is written as class Act : NSObject, the corresponding declaration can be compiled. You can also use @objc to declare it, but this is still the same, class *** inherits NSObject. Like below:

  1. import Foundation
  2.    
  3. @objc (Act)
  4.    
  5. class Act
  6. {
  7. func hasAct(tag:Int) -> String
  8. {
  9. switch (tag)
  10. {
  11. case   1 : return   "Movie"    
  12. case   2 : return   "CCTV"    
  13. case   3 : return   "Sport TV"    
  14. default : return   "Area TV"    
  15. }
  16. }
  17.    
  18. @objc (init) // I thought I could find it by adding alloc, but it doesn't work...  
  19. init()
  20. {
  21. println( "act constructor is called." )
  22. }
  23.        
  24. deinit
  25. {
  26. println( "act destroyed is called." )
  27. }
  28. }

But when you use it, you will find

act = [[Act alloc]init]; //Error, alloc not found, so it is recommended that you inherit NSObject.

<<:  Cyanogen and Microsoft reach strategic partnership to bundle Microsoft apps

>>:  Swift TIP: objc and dynamic

Recommend

By 2023, how far has the genomics revolution progressed?

Original title: 70th anniversary of the discovery...

How much does it cost to develop a marriage and love app in Linfen?

There are two types of Linfen marriage and love a...

How to use Zhihu promotion to efficiently attract targeted users?

“Zhihu, share your newly made story with the worl...

Can Android imitate Zhihu's creative advertising be played like this?

1. Overview It seems that I saw a very unique way...

Where is the traffic pool for educational institutions in 2021?

In 2020, affected by the COVID-19 pandemic, the o...

Why are the old domestic appliances from 20 years ago so durable?

After a full twenty years of service, a domestic ...

How to distinguish between Douyin information flow delivery and Douyin+?

According to official statistics, the official da...

In 7 days, we tested 5 fission models!

The article tests the funnel models of 5 fission ...

Ranking optimization analysis of the 6 major Android markets!

We are always talking about the ranking mechanism...

A poster that goes viral requires these 8 elements

An important marketing component of an event is p...