我在一个单例中制作了一个数组,以将代码的多个部分写入对象。方法如下:
// in singleton.h
#import <UIKit/UIKit.h>
// make globally accessible array
@interface MyManager : NSObject {
NSMutableArray *imgArray;
}
@property (nonatomic, retain) NSMutableArray *imgArray;
+ (id)sharedManager;
@end
// in singleton.m
#import "singleton.h"
对于我的.m文件:
@implementation MyManager
@synthesize imgArray;
#pragma mark Singleton Methods
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id) init {
if (self = [super init]) {
self.imgArray = [NSMutableArray new];
}
NSLog(@"initialized");
return self;
}
@end
我可以从目标C代码访问名为imgArray的数组。但是,在执行此操作时,我很快得到了一个错误:
let array = MyManager.sharedManager()
array.imgArray.add("hello world") . (!!!) Value of type 'Any?' has no member 'imgArray'
我可以访问MyManager.sharedManager()
,但是为什么不能像在目标C中一样访问imgArray
?
答案 0 :(得分:2)
将+ (id)sharedManager;
更改为+ (MyManager *)sharedManager;
。否则,Swift不知道对象sharedManager
是哪种类型,它将假定它是Any
。
答案 1 :(得分:2)
您应将其声明为instancetype
或MyManager *
。例如
+ (MyManager *)sharedManager;
或
+ (instancetype)sharedManager;
一些建议:
单例的Swift约定是使用类属性名称为shared
,而不是类方法为sharedManager()
。当您在Objective-C中声明它时,您可能想明确地说它是一个类属性:
@property (class, readonly, strong) MyManager *sharedManager NS_SWIFT_NAME(shared);
这不会改变任何Objective-C的行为,但是在Swift中,您可以执行以下操作:
let manager = MyManager.shared
manager.images.add(image)
这将导致更简洁,更惯用的Swift代码。
我建议您审核Objective-C的可为空性。也就是说,确认什么是nil
,什么不能。由于imgArray
(我可能会简称为images
)和sharedManager
都不能成为nil
,因此我只使用NS_ASSUME_NONNULL_BEGIN
/ END
告诉编译器“除非另有说明,否则假设此属性不能为nil
”的宏:
// MyManager.h
@import UIKit;
NS_ASSUME_NONNULL_BEGIN
@interface MyManager : NSObject
@property (nonatomic, strong) NSMutableArray <UIImage *> *images;
@property (class, readonly, strong) MyManager *sharedManager NS_SWIFT_NAME(shared);
@end
NS_ASSUME_NONNULL_END
通过告诉编译器这两个不能为nil
,这意味着您将不必在Swift代码中减少不必要的可选选项的包装。
顺便说一句,请注意,我没有声明实例变量。 (如果您确实需要它,我不建议在公共界面中声明它。)Objective-C现在将自动为我们合成支持我们属性的ivars。 (因此,我的财产images
将具有一个称为_images
的ivar,它将为我合成。)而且,您也不需要/不需要@synthesize
行:
// MyManager.m
#import "MyManager.h"
@implementation MyManager
+ (instancetype)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (instancetype)init {
if (self = [super init]) {
self.images = [NSMutableArray new];
}
NSLog(@"initialized");
return self;
}
@end