ios – 自我参考迅速关闭

我在
swift中有一个懒惰的属性,它有一个看起来像这样的回调.

lazy var apiClient: MyApiClient =
    {

        var apiClient : MyApiClient = MyApiClient()

        apiClient.detailSearchFinishedCallBack = {
            (detailModel : DetailModel!) in

        }

        return apiClient
    }()

我有另一个懒惰的load属性,我想在闭包内访问,如下所示:

  lazy var loadingView : LoadingView =
    {
        var loadingView : LoadingView = LoadingView()
        loadingView.frame = CGRectMake(0, 0, 200, 200)
        loadingView.center = self.view.center

        return loadingView
    }()

但是,我无法引用闭包内的加载视图.在目标c中,这看起来像这样.

-(LoadingView *)loadingView
{
    if(!_loadingView)
    {
        _loadingView = [LoadingView new];
        _loadingView.frame = CGRectMake(0, 0, 200, 200);
        _loadingView.center = self.view.center;
    }
    return _loadingView;
}

-(MyApiClient *)apiClient
{
    if(!_apiClient)
    {
        _apiClient = [MyApiClient new];

        __weak FeedViewController *_self = self;

        self.apiClient.detailSearchFinishedCallBack = ^(DetailModel  *detailModel)
        {
              [_self.loadingView stopAnimating];
        };
    }

    return _apiClient;
}

有人能够在Swift中向我展示相同的内容吗?

更新:

  lazy var apiClient: MyApiClient = {
            let apiClient: MyApiClient = MyApiClient()
            apiClient.detailSearchFinishedCallBack = { [weak self] (detailModel: DetailModel!) in

                println(self?.loadingView.frame)

                return
            }
            return apiClient
            }()

所以我继续尝试实现提议的解决方案,但是我收到了编译错误.具体来说,我遇到了这个错误:

命令/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc失败,退出代码为1

我不确定这是否与我的项目中的swift配置有关,但我正在使用桥接头来导入我的目标c头文件以暴露给Swift.我无法想到任何其他可能导致这种情况的事情,但任何帮助都将得到解决.

最佳答案 语法是:

lazy var apiClient: MyApiClient = {
    let apiClient: MyApiClient = MyApiClient()
    apiClient.detailSearchFinishedCallBack = { [weak self] detailModel in
        self?.loadingView?.stopAnimating()
    }
    return apiClient
}()

当我最初回答这个问题时,Swift编译器在解释上述语法时遇到了问题,因此我提出了下面概述的以下丑陋的解决方法.但您现在可以使用上述简单的逻辑语法.

原始答案:

您正在使用闭包为属性提供默认值.但是在Swift编程语言的Initialization章节中使用Closure或Function设置默认属性值部分说:

Note: If you use a closure to initialize a property, remember that the rest of the instance has not yet been initialized at the point that the closure is executed. This means that you cannot access any other property values from within your closure, even if those properties have default values. You also cannot use the implicit self property, or call any of the instance’s methods.

话虽如此,人们可以提出一个论点,即编译器应该允许惰性变量,但事实并非如此.

您说您想要实现此Objective-C代码:

-(MyApiClient *)apiClient
{
    if(!_apiClient)
    {
        _apiClient = [MyApiClient new];

        __weak FeedViewController *_self = self;

        self.apiClient.detailSearchFinishedCallBack = ^(DetailModel  *detailModel)
        {
              [_self.loadingView stopAnimating];
        };
    }

    return _apiClient;
}

也许您可以考虑使用由计算属性处理的私有存储属性的更直接的Swift转换:

private var _apiClient: MyApiClient!

var apiClient: MyApiClient {
    if _apiClient == nil {
        _apiClient = MyApiClient()

        _apiClient.detailSearchFinishedCallBack = { [weak self] detailModel in
            if let loadingView = self?.loadingView {
                loadingView.stopAnimating()
            }
        }
    }

    return _apiClient
}

注意,这不是线程安全的(但是你的Objective-C再现也不是),但它完成了你的要求.

除此之外,还有其他方法可以解决这个问题:

>您可以将初始化代码从这些闭包中移动到其他逻辑共享初始化例程中,例如, viewDidLoad或你有什么.这样,事物初始化的顺序是明确且明确的.
>您可以通过让视图可以观察到的API发布通知来进一步将API与UI分离.

点赞