Objective-C pointer and Swift2

Source: Internet
Author: User

Objective-C pointer and Swift2

 

Use Objective-C in Swift to read the C pointer in Swift

The following Objective-C method returnsintPointer, or in the C term(int *):

@interface PointerBridge : NSObject {    int count;}- (int *) getCountPtr;@end@implementation PointerBridge- (instancetype) init {    self = [super init];    if(self) {        count = 23;    }    return self;}- (int *) getCountPtr {    return &count;}@end

The above Code definesPointerBridgeClass, which containsgetCountPtrMethod, this method returns a value of 23intTypeMemory Address. ThisIntActuallycountIn the constructorinitIs assigned to 23.

I put this code in a Objective-C header file, and then import this header file into my bridging header file (XXX-bridging-header.h) so that it can be used in Swift. Then I create a name in Swift namedbridgeOfPointerBridgeInstance, and then obtaingetCountPtr()Method return value...

let bridge = PointerBridge()let theInt = bridge.getCountPtr()print(theInt)print(theInt.memory)

In Xcode, press and hold the Option key and clicktheIntCheck its type and you will find that its Swift type isUnsafeMutablePointer . This is pointingIntType pointer, andIntType is different, it just points to itPointer.

If you run this program and then execute this Swift code, we will find thattheIntOutput in the command line is similar0x00007f8bdb508ef8The memory address, and then we will seememoryThe output value of the member variable is 23. The memory pointed to by the Access pointer usually returns the objects pointed to at the underlying layer. In this example, it is the original 32-bitint(In SwiftInt32)

Now let the Objective-C class support settingscount.

@interface PointerBridge : NSObject {    int count;}- (int *) getCountPtr;- (void) setCount:(int)newCount;@end@implementation PointerBridge- (instancetype) init {    self = [super init];    if(self) {        count = 23;    }    return self;}- (int *) getCountPtr {    return &count;}- (void) setCount:(int)newCount {    count = newCount;}@end

We can callsetCount()Method To modifycount. BecausetheIntIs a pointer, sosetCountModifycountWill also be updatedtheInt.memory. Don't forget that the memory address will not change, but the value will change.

That is to say, the following code prints the number 23 in the command line, and then prints the number 1000.

let bridge = PointerBridge()let theInt = bridge.getCountPtr()print(theInt.memory) // 23bridge.setCount(1000)print(theInt.memory) // 1000

If you want to avoid writing.memoryThere is a shortcut.memoryAssign a value to a variable:

let bridge = PointerBridge()let theInt = bridge.getCountPtr()let countVal = theInt.memoryprint(countVal) // 23

As before, the command line outputs 23. However, if we callsetCount()Method ModificationcountValue, the problem occurs:

let bridge = PointerBridge()let theInt = bridge.getCountPtr()let countVal = theInt.memoryprint(countVal) // 23bridge.setCount(1000)print(countVal) // 23

The cause of the problem iscountValYesValue). When assigning valuesValue)Is 23, socountValIt has its own memory address, which permanently saves the value 23, so it has lost the pointer feature.countValNow it's just a normalInt32Type.

Create a C pointer in Swift

What if we want to do the opposite? Not usedIntTypecountAssign a value, but pass in a pointer?

Let's assume that the Objective-C Code contains the following method:

- (void) setCountPtr:(int *)newCountPtr {    count = *newCountPtr;}

This method is very useful, but it is actuallynewCountPtrAssign a value to count again, but in Swift development, you will indeed encounter such scenarios that require pointer input. This is just to show you how to create a pointer type in Swift and then pass it into the Objective-C method.

You may simply think that you can pass in a reference operator similar &IntValue, as you did in C. In Objective-C, you can write as follows:

int mcount = 500;[self setCountPtr:&mcount];

This code can successfullycountThe value is updated to 500. However, in Swift, you will find it more complex (and lengthy) through automatic completion ). It needs to inputUnsafeMutablePointer TypenewCountPtrVariable.

I know this type is disgusting and it looks complicated. But in fact it is quite simple, especially when you know the pointer in Obj-C. If you want to createUnsafeMutablePointer Type object, we only need to call the constructor method. The only parameter that needs to be passed in this constructor is the pointer size (you should know that the pointer to C is not of the storage type, so it does not store the size information)

let bridge = PointerBridge()let theInt = bridge.getCountPtr()print(theInt.memory) // 23let newIntPtr = UnsafeMutablePointer
  
   .alloc(1)newIntPtr.memory = 100bridge.setCountPtr(newIntPtr)print(theInt.memory) // 100
  

UniqueUnsafeMutablePointer The input parameter in the constructor is the number of objects that need to be allocated space, so we can pass in 1, because we only need oneInt32Object. Then, you just needmemoryIn turn, we can assign values to the newly created pointer. In the end, we only neednewIntPtrInputsetCountrPtrMethod.theIntWhen the pointer value is printed, we can see that its value has been updated to 100.

Summary

UnsafeMutablePointer Sibling typeUnsafePointer Basically, it is just an abstraction of the C pointer. You can think of them as optional types of Swift, which is easier to understand. They are not directly equal to an exact value, but are abstracted over an exact value. They are generic, so that they can use other values, not justInt32. For example, you need to inputFloatObject, you may needUnsafeMutablePointer .

The point is:Int Strong ConversionIsUnsafeMutablePointer Because the pointer is not a simpleIntValue. Therefore, to create a new object, you must call the constructor.UnsafeMutablePointer (count: Int) .

After this article, we will continue to study some details about function pointers and learn how to use the advantages of these features to better interact with APIs of C and Objective-C. Register our Newsletter so that you will not miss these wonderful contents!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.