Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@zwtin

Objective-Cクラスを継承したSwiftクラスで、継承元のメンバ変数を扱う方法

はじめに

古くから存在するアプリでは、Objective-CとSwiftが共存していることがよくあります。はじめはObjective-Cで作られ、Swiftが発表された後はSwiftで作っている、というパターンですね。こういったアプリでは、Objective-Cで書かれたクラスをSwiftで継承する、という実装を行う場面が出てくると思います。そのときのメンバ変数の取り扱いで少し手間取ったので、備忘録として残します。

サンプルファイル

以下に、この記事で扱うファイルを記載します。

継承元のObjective-Cファイル

継承元のクラスが書かれたファイルは以下であるとします。

SampleParentViewController.h

#import <UIKit/UIKit.h>

@protocol SampleDelegate

- (void) delegateMethod;

@end

@interface SampleParentViewController: UIViewController {
    id<SampleDelegate> sampleDelegate;
}

- (instancetype)initWithDelegate:(id<SampleDelegate>)delegate;

@end
SampleParentViewController.m

#import "SampleParentViewController.h"

@implementation SampleParentViewController

- (instancetype)initWithDelegate:(id<SampleDelegate>)delegate
{
    self = [super init];
    if (self) {
        sampleDelegate = delegate;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [sampleDelegate delegateMethod];
}

@end

継承先のSwiftファイル

以下のように、継承するクラスをSwiftで書いたとします。

SampleChildViewController.swift
import UIKit

class SampleChildViewController: SampleParentViewController {

    let otherViewController: SampleDelegate = OtherViewController()

    override func viewDidLoad() {
        self.sampleDelegate = otherViewController
        super.viewDidLoad()
    }
}

しかし、このSwiftファイルをつくるとコンパイルエラーになります。以下で、このファイルの実装するための変更手順を示していきます。

変更手順

段階を追って、意図通りに動くための手順を示していきます。

プロパティを追加

まずこのsampleDelegateはメンバ変数として定義されているため、クラスの外から参照することはできません。参照できるようにするには、メンバ変数ではなくプロパティに変更する必要があります。そのために、まずはヘッダファイルにプロパティの宣言を追加します。

SampleParentViewController.h

#import <UIKit/UIKit.h>

@protocol SampleDelegate

- (void) delegateMethod;

@end

@interface SampleParentViewController: UIViewController {
    id<SampleDelegate> sampleDelegate;
}

@property id<SampleDelegate> sampleDelegate;

- (instancetype)initWithDelegate:(id<SampleDelegate>)delegate;

@end

一応、これだけでコンパイルエラーは解消します。しかし、実行してみるとotherViewControllerのdelegateMethodは実行されず、sampleDelegateは書き換えられていないことがわかります。これはヘッダファイルで新しくプロパティを宣言し変数を追加しましたが、もともとのsampleDelegateには何の変更も加わっていないためです。

Objective-Cのプロパティ

Objective-Cでは、ヘッダファイルでプロパティを宣言すると、メソッドファイルでは頭に_がついて扱われます。そのため現時点では、もともと存在していたsampleDelegateと新しく追加した_sampleDelegateが存在していることになっています。今回はsampleDelegateをプロパティに置き換えるのが目的なので、メソッドファイルに書かれているsampleDelegateを_sampleDelegateに書き換えていきます。

SampleParentViewController.m

#import "SampleParentViewController.h"

@implementation SampleParentViewController

- (instancetype)initWithDelegate:(id<SampleDelegate>)delegate
{
    self = [super init];
    if (self) {
        _sampleDelegate = delegate;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [_sampleDelegate delegateMethod];
}

@end

これで、sampleDelegateが完全にプロパティに置き換わりました。したがって継承先のファイルからsampleDelegateが扱えるようになっています。一応、使わなくなったメンバ変数のsampleDelegateの宣言を消しておきましょう。

SampleParentViewController.h

#import <UIKit/UIKit.h>

@protocol SampleDelegate

- (void) delegateMethod;

@end

@interface SampleParentViewController: UIViewController

@property id<SampleDelegate> sampleDelegate;

- (instancetype)initWithDelegate:(id<SampleDelegate>)delegate;

@end

まとめ

メンバ変数が定義されているObjective-CファイルをSwiftファイルで継承してその変数を扱うために、プロパティで宣言し直してメソッドファイルを書き換える手順を記載しました。Objective-Cはハマると解決に時間がかかる仕様が多いと思います。そんな人の助けになれると幸いです。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
zwtin
某Web系企業でアプリエンジニアやってます。 iOS専門でしたが、最近Androidの勉強を始めました。 趣味でUnityも少しだけやってます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?