Не удается получить доступ к массиву синглтона Objective-C из кода Swift - PullRequest
0 голосов
/ 05 марта 2019

Я создал массив в одиночном коде для записи в него объектов из нескольких частей моего кода.Вот как:

// 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

Я могу получить доступ к своему массиву imgArray из моего объективного кода C.Тем не менее, в быстром я получаю сообщение об ошибке:

let array  = MyManager.sharedManager()

array.imgArray.add("hello world") .    (!!!) Value of type 'Any?' has no member 'imgArray'

Я могу получить доступ к MyManager.sharedManager(), но Почему я не могу получить доступ к imgArray так же, как в цели C?

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Вы должны объявить его как instancetype или MyManager *.Например,

+ (MyManager *)sharedManager;

или

+ (instancetype)sharedManager;

Несколько предложений:

  1. Соглашение Swift для синглтона заключается в использовании классаимя свойства shared, а не метод класса sharedManager().Когда вы объявляете это в Objective-C, вы можете явно указать, что это свойство класса:

    @property (class, readonly, strong) MyManager *sharedManager NS_SWIFT_NAME(shared);
    

    Это не изменит поведение Objective-C, но в Swift вы можете простоdo:

    let manager = MyManager.shared
    manager.images.add(image)
    

    В результате получается более лаконичный и идиоматичный код Swift.

  2. Я бы посоветовал вам проверить 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..

  3. Кстати, обратите внимание, что я не объявлял переменную экземпляра.(А если он вам нужен, я бы не советовал объявлять его в общедоступном интерфейсе.) Теперь Objective-C будет автоматически синтезировать ивары, поддерживающие наши свойства.(Таким образом, моя собственность images будет иметь ивар под названием _images, который будет синтезирован для меня.) И вам не нужна / не нужна строка @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
    
0 голосов
/ 05 марта 2019

Измените + (id)sharedManager; на + (MyManager *)sharedManager;.В противном случае Свифт не знает, что это за объект sharedManager, и предположит, что это Any.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...