本文介绍: 本文目录一、前言二、代码结构三、不同数据类型下在Swift中的用法1.在Swift使用NSDictionary2.类型转换失败导致程序崩溃3.在Swift使用NSMutableDictionary4.在Swift使用NSDictionary+范型5.在Swift使用NSMutableDictionary+范型6.在Swift使用Bool、Bool*四、附录:Swift完整代码一、前言上文说到,在OC/Swift混编下,对属性参数数据类型如下建议:1.尽可能多地使用不可类型,尽可能

一、前言

上文说到,在OC/Swift混编下,对属性参数数据类型如下建议

本文通过一个简单实例解释为什么要这样做。

二、代码结构

假设一个OC的模型如下

@interface TestDataModel : NSObject

@property (nonatomic, strong) NSDictionary                      *dict1;
@property (nonatomic, strong) NSMutableDictionary               *dict2;
@property (nonatomic, strong) NSDictionary<NSString*,id>        *dict3;
@property (nonatomic, strong) NSMutableDictionary<NSString*,id> *dict4;
@property (nonatomic, strong) NSDictionary                      *errorTypeDict;

@property (nonatomic, assign) BOOL boolValue;
@property (nonatomic, assign) BOOL *boolPtrValue;

-(void)printBool:(BOOL)boolValue;
-(void)printBoolPtr:(BOOL*)boolPtrValue;

@end

@implementation TestDataModel

-(instancetype)init {
    if( self=[super init] ) {
        self.dict1 = @{
            @"strKey":@"strValue",
            @"boolKey":@(YES),
            @"dictKey":@{@"key":@"value"}
        };
        self.dict2 = [NSMutableDictionary dictionaryWithDictionary:self.dict1];
        self.dict3 = [self.dict1 copy];
        self.dict4 = [NSMutableDictionary dictionaryWithDictionary:self.dict1];
        self.errorTypeDict = @{@1:@1,@2:@2,@3:@3};
        self.boolValue = YES;
        self.boolPtrValue = &amp;_boolValue;
    }
    return self;
}

-(void)printBool:(BOOL)boolValue
{
    NSLog(@"boolValue = %d",boolValue);
}

-(void)printBoolPtr:(BOOL*)boolPtrValue
{
    if( boolPtrValue==nil ){
        NSLog(@"boolPtrValue = nil");
        return ;
    }
    NSLog(@"boolValue = %d",*boolPtrValue);
}

main.m调用Swift类的代码如下:

#import "studyObjc-Swift.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        [[[TestSwift alloc] init] main];
    }
    return 0;
}

Swift的代码框架如下

import Foundation

@objcMembers
class TestSwift:NSObject {
    
    private func testDict1(){
       
    }
    
    private func testDict2(){
        
    }
    
    private func testDict3(){
        
    }

    private func testDict4(){

    }
    
    private func testErrorTypeDict(){
        
    }
    
    private func testBool(){
        
    }
    
    private func testBoolPtr(){
        
    }
    
    public func main(){
        testDict1()
        testDict2()
        testDict3()
        testDict4()
        testErrorTypeDict()
        testBool()
        testBoolPtr()
    }
}

三、不同数据类型下在Swift中的用法

接下来我们开始尝试在Swift代码中调用OC的TestDataModel

1.在Swift中使用NSDictionary

首先,如果我们testDict1方法中,直接采取如下写法编译

private func testDict1(){
        let swDict1:[String:Any] = TestDataModel.init().dict1
        print(swDict1)
}

此时,编译器报错

Cannot assign value of type '[AnyHashable : Any]' to type '[String : Any]'

原因是,NSDictionary没有使用泛型指定类型时,默认情况下,在Swift中会认为其类型是[AnyHashable : Any]

此时,为了能将dict1的值成功赋值给swDict1,我们必须做一个类型转换,代码如下

private func testDict1(){
        let swDict1:[String:Any] = TestDataModel.init().dict1 as! [String:Any]
        print(swDict1)
}

It Works,看起来不错。

但实际上,当你看到as!时,你就应该意识到,当dict1强制类型转换[String:Any]发生失败,那么程序就会crash!!!

2.类型转换失败导致程序崩溃

为了证明这一点,接下来我们在testErrorTypeDict方法里,实现如下写法

private func testErrorTypeDict(){
        let swErrorTypeDict:[String:Any] = TestDataModel.init().errorTypeDict as! [String:Any]
        print(swErrorTypeDict)
}

编译运行,程序崩溃,并打印如下信息

Could not cast value of type 'Swift.AnyHashable' (0x7fff81603d58) to 'Swift.String' (0x7fff81606180).

3.在Swift中使用NSMutableDictionary

接下来我们尝试在Swift中使用NSMutableDictionary类型的属性,在使用时,同样的也需要对其进行强制类型转换,其代码如下

private func testDict2(){
        let swDict2:[String:Any] = TestDataModel.init().dict2 as! [String:Any]
        print(swDict2)
}

4.在Swift中使用NSDictionary+范型

最后我们尝试在Swift中使用NSDictionary<NSString*,id>类型的属性,代码如下:

private func testDict3(){
        let swDict3:[String:Any] = TestDataModel.init().dict3
        print(swDict3)
}

我们看到,其赋值过程是无比的丝滑、顺利,在代码层面不需要任何的类型转换

5.在Swift中使用NSMutableDictionary+范型

那么,问题来了,NSMutableDictionary<NSString*,id>可以很丝滑、很顺利的直接赋值吗?
答案是否定的,其代码如下:

private func testDict4(){
        let swDict4:[String:Any] = TestDataModel.init().dict4 as! [String : Any]
        print(swDict4)
}

6.在Swift中使用Bool、Bool*

写的有些累了,省略废话,对于最后一条建议的反例如下:

private func testBool(){
        let swBool:Bool = true
        TestDataModel.init().print(swBool)
}
private func testBoolPtr(){
        let swBool:ObjCBool = true
        let swBoolPtr = UnsafeMutablePointer<ObjCBool>.init(&amp;swBool)
        TestDataModel.init().printBoolPtr(swBoolPtr)
}

我们发现,在OC中基本数据类型一旦使用到指针时,就需要在Swift中手工创建UnSafeMutablePointer对象,使用起来是非常麻烦的,因此,尽量避免在OC的方法的参数或者属性中使用指针/二级指针

本文例子中,我们可以从Swift使用层面深刻体会到前文提到的那些建议的好处,那么,OC对象转Swift对象背后是怎么实现的呢?请参考下文。

四、附录:Swift完整代码

Swift的完整代码

import Foundation

@objcMembers
class TestSwift:NSObject {
    
    private func testDict1(){
        let swDict1:[String:Any] = TestDataModel.init().dict1 as! [String:Any]
        print(swDict1)
    }
    
    private func testDict2(){
        let swDict2:[String:Any] = TestDataModel.init().dict2 as! [String:Any]
        print(swDict2)
    }
    
    private func testDict3(){
        let swDict3:[String:Any] = TestDataModel.init().dict3
        print(swDict3)
    }
    
    private func testDict4(){
        let swDict4:[String:Any] = TestDataModel.init().dict4 as! [String : Any]
        print(swDict4)
    }

    private func testErrorTypeDict(){
//        let swErrorTypeDict:[String:Any] = TestDataModel.init().errorTypeDict as! [String:Any]
//        print(swErrorTypeDict)
    }
    
    private func testBool(){
        let swBool:Bool = true
        TestDataModel.init().print(swBool)
    }
    
    private func testBoolPtr(){
        var swBool:ObjCBool = true
        var swBoolPtr = UnsafeMutablePointer<ObjCBool>.init(&amp;swBool)
        TestDataModel.init().printBoolPtr(swBoolPtr)
    }
    
    public func main(){
        testDict1()
        testDict2()
        testDict3()
        testErrorTypeDict()
        testBool()
        testBoolPtr()
    }
    
}

原文地址:https://blog.csdn.net/gaoben668/article/details/122672710

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_36584.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注