7

私のアプリケーションには、ユーザーに質問するためにUIViewController多くのことを使用する があります。UIAlertView

UIAlertViewコントローラーを のデリゲートにしたそれぞれの応答が必要なので、UIAlertViewDelegateこれは正常に機能しますが、7 UIAlertView'si`m の後、デリゲートを使用するより良い方法を見つけようとしています。

Javaでは、次の質問のように、単一の目的でインラインクラスを作成できることを知っています: Java - インラインクラス定義

私が知りたいのは、動的にデリゲートするクラスを作成する方法はありますか? このようなことを達成するために

id<UIAlertViewDelegate> myCustomClass = @class {
    my class code goes here
}

UIAlertView* alertView;
alertView = [[UIAlertView alloc] initWithTitle:@"Title"
                                       message:@"Message"
                                      delegate:myCustomClass
                             cancelButtonTitle:@"No"
                             otherButtonTitles:@"OK", @"Sure", @"Maybe", nil] ];    
[alertView show];
4

2 に答える 2

14

いいえ - Objective-C には「インライン クラス」はありません。そうは言っても、 Objective-C を使用して実行時にカスタムオブジェクトを作成できますが、これはもう少し複雑ですが、あなたが言っていることを実行するためのコードを喜んで共有します.

その例を次に示します。

NSObject+Subclass.h

#import <objc/runtime.h>

typedef struct selBlockPair { SEL aSEL; id (^__unsafe_unretained aBlock)(id, ...); } selBlockPair;
#define NIL_PAIR ((struct selBlockPair) { 0, 0 })
#define PAIR_LIST (struct selBlockPair [])
#define BLOCK_CAST (id (^)(id, ...))

@interface NSObject (subclass)

+(Class) newSubclassNamed:(NSString *) name
            protocols:(Protocol **) protos
                 impls:(selBlockPair *) impls;

@end

NSObject+Subclass.m

@implementation NSObject (subclass)

+(Class) newSubclassNamed:(NSString *)name
             protocols:(Protocol **)protos
                 impls:(selBlockPair *)impls
{
    if (name == nil)
    {
        // basically create a random name
        name = [NSString stringWithFormat:@"%s_%i_%i", class_getName(self), arc4random(), arc4random()];
    }

    // allocated a new class as a subclass of self (so I could use this on a NSArray if I wanted)
    Class newClass = objc_allocateClassPair(self, [name UTF8String], 0);

    // add all of the protocols untill we hit null
    while (protos && *protos != NULL)
    {
        class_addProtocol(newClass, *protos);
        protos++;
    }

    // add all the impls till we hit null
    while (impls && impls->aSEL)
    {
        class_addMethod(newClass, impls->aSEL, imp_implementationWithBlock(impls->aBlock), "@@:*");
        impls++;
    }

    // register our class pair
    objc_registerClassPair(newClass);

    return newClass;
}

@end

使用例:

int main()
{
    @autoreleasepool {
        __strong Class newClass = [NSString newSubclassNamed:@"MyCustomString" protocols:NULL impls: PAIR_LIST {
            @selector(description),
            BLOCK_CAST ^id (id self) {
                return @"testing";
            },
            NIL_PAIR
        }];

        NSString *someString = [newClass new];
        NSLog(@"%@", someString);
    }
}

出力:

2012-10-01 10:07:33.609 TestProj[54428:303] テスト
于 2012-10-01T13:46:50.030 に答える
3

このタイプの Java 匿名内部クラスは、Objective-C ではサポートされていません。デリゲートに個別に応答したい場合は、ブロックを試してみることをお勧めします。

残念ながら、Apple は UIAlertViews にブロックを追加していませんが、自分で実装できます。多くの人がこれをオンラインで行いました。こちらをご覧ください: http://blog.mugunthkumar.com/coding/ios-code-block-based-uialertview-and-uiactionsheet/またはhttps://github.com/MugunthKumar/UIKitCategoryAdditions

基本的な考え方は、サブクラス (または関連付けられたオブジェクトを使用する場合はカテゴリ) を作成し、それが独自のデリゲートになり、渡したブロックを呼び出すように独自のデリゲートに指示できるということです。

于 2012-10-01T13:47:05.697 に答える