Преобразование ленивого экземпляра Objective-C с побочными эффектами в Swift

Я преобразовал приложение Obit-C Dropit из курса Stanford CS193P в Swift. Оригинальный код находится по адресу:

http://web.stanford.edu/class/cs193p/cgi-bin/drupal/

Есть многократное использование отложенной реализации, которая выполняет дополнительную инициализацию или вызывает некоторый другой побочный эффект. Мое преобразование в Swift работает, но я не уверен, что это правильное решение или следует полностью избегать такого рода кодирования Objective-C? Первые примеры просто устанавливают некоторые свойства как часть отложенной реализации.

- (UIGravityBehavior *)gravity
{
    if (!_gravity) {
        _gravity = [[UIGravityBehavior alloc] init];
        _gravity.magnitude = 0.9;
    }
    return _gravity;
}

- (UICollisionBehavior *)collider
{
    if (!_collider) {
        _collider = [[UICollisionBehavior alloc] init];
        _collider.translatesReferenceBoundsIntoBoundary = YES;
    }
    return _collider;
}

Моя версия Swift:

@lazy var gravity: UIGravityBehavior = {
    var tempGravity = UIGravityBehavior()
    tempGravity.magnitude = 0.9
    return tempGravity
    }()
@lazy var collider: UICollisionBehavior = {
    var tempCollider = UICollisionBehavior()
    tempCollider.translatesReferenceBoundsIntoBoundary = true
    return tempCollider
    }()

Есть ли более понятный способ инициализации в Swift?

ViewController из Objective-C для второго примера немного сложнее:

@interface DropitViewController () <UIDynamicAnimatorDelegate>
@property (weak, nonatomic) IBOutlet UIView *gameView;
@property (strong, nonatomic) UIDynamicAnimator *animator;
@property (strong, nonatomic) DropitBehavior *dropitBehavior;
@end

@implementation DropitViewController

static const CGSize DROP_SIZE = { 40, 40 };

- (DropitBehavior *)dropitBehavior
{
    if (!_dropitBehavior) {
        _dropitBehavior = [[DropitBehavior alloc] init];
        [self.animator addBehavior:_dropitBehavior];
    }
    return _dropitBehavior;
}

- (UIDynamicAnimator *)animator
{
    if (!_animator) {
        _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.gameView];
        _animator.delegate = self;
    }
    return _animator;
}

В Свифте:

class ViewController: UIViewController, UIDynamicAnimatorDelegate {
    @IBOutlet var gameView: UIView

    let DROP_SIZE = CGSize(width: 40.0, height: 40.0)

    // lazy instantiation with closures
    @lazy var animator: UIDynamicAnimator = {
        var tempAnimator = UIDynamicAnimator(referenceView: self.gameView)
        tempAnimator.delegate = self
        return tempAnimator
    }()
    @lazy var dropitBehavior: DropitBehavior = {
        var tempBehavior = DropitBehavior()
        // side effect...
        self.animator.addBehavior(tempBehavior)
        return tempBehavior
    }()

То, как была разработана программа, во время ленивой инициализации dropitBehavior - это когда аниматор создается впервые, а затем dropitBehavior добавляется в аниматор. Это можно проверить с помощью println, в отладчике и т. Д.

Обратите внимание, что есть связанный вопрос: Ленивый экземпляр UIDynamicAnimator с referenceView - Swift

Тем не менее, предлагаемое решение, по-видимому, заключается в том, чтобы избежать @lazy, использовать дополнительные параметры и перенести работу в viewDidLoad, что тоже не кажется таким уж хорошим.

Существует много кода Objective-C, подобного этому, для перевода, поэтому я хотел бы узнать, как это сделать в Swift.

0 ответов

Другие вопросы по тегам