2012-10-01 32 views
6

Trong ứng dụng của tôi, tôi có một số UIViewController mà tôi sử dụng rất nhiều UIAlertView để hỏi mọi thứ cho người dùng.Tạo các lớp động tùy chỉnh trong mục tiêu-c

Vì tôi cần đáp ứng của mỗi UIAlertView tôi đã làm cho bộ điều khiển của tôi là đại biểu của UIAlertViewDelegate, điều này hoạt động tốt nhưng sau 7 UIAlertView 's i' m cố gắng tìm một cách tốt hơn để sử dụng đại biểu.

Trong java tôi biết rằng tôi có thể tạo lớp inline cho một mục đích duy nhất, như trong câu hỏi này: Java - inline class definition

gì tôi muốn biết là: Có cách nào để tạo ra một lớp học để được đại biểu tự động? để đạt được điều gì đó như thế này

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]; 
+0

'@ class' có một ý nghĩa hoàn toàn khác trong Obj-C so với những gì bạn đang nghĩ. Nó tuyên bố một lớp 'chuyển tiếp', FYI. –

+1

điểm của việc sử dụng '' @ class'' chỉ là để cho thấy một cái gì đó tương tự, để giúp tôi giải thích cho bất cứ ai những gì tôi đang suy nghĩ. chỉ là –

Trả lời

14

Không - không có 'lớp nội tuyến' trong Mục tiêu-C. Với điều đó đã nói, bạn có thể tạo các đối tượng tùy chỉnh tại thời gian chạy với mục tiêu-c, có liên quan nhiều hơn một chút, nhưng tôi sẵn lòng chia sẻ một số mã để làm những gì bạn đang nói.

Dưới đây là một ví dụ về điều đó:

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 

Ví dụ Cách sử dụng:

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); 
    } 
} 

Output:

 
2012-10-01 10:07:33.609 TestProj[54428:303] testing 
+0

Câu trả lời của bạn đã trả lời tất cả câu hỏi của tôi về các lớp nội tuyến và đã mở một loạt câu hỏi khác về mã của bạn. Cảm ơn bạn thật. bây giờ tôi đang cố gắng hiểu mã này mà bạn đã đăng. cảm ơn một lần nữa –

+0

@NicosKaralis không có vấn đề, nếu bạn có bất kỳ vấn đề hiểu biết, đừng ngại hỏi! –

+0

Brilliant! Một câu hỏi nhanh, có cách nào dễ dàng để gọi '[mô tả siêu]' trong impl tùy chỉnh không? – ccwasden

3

Đây là loại Java lớp bên trong vô danh không phải là cái gì đó được hỗ trợ trong Objective-C. Nếu bạn muốn trả lời riêng các đại biểu, tôi có cách tốt để thử nghiệm với các khối.

Thật không may, Apple chưa thêm các khối vào UIAlertViews, nhưng bạn có thể tự mình triển khai chúng. Một nhóm người đã làm điều này trực tuyến. Hãy xem tại đây: http://blog.mugunthkumar.com/coding/ios-code-block-based-uialertview-and-uiactionsheet/ hoặc https://github.com/MugunthKumar/UIKitCategoryAdditions.

Ý tưởng cơ bản là bạn có thể tạo một lớp con (hoặc một loại nếu sử dụng đối tượng liên quan), đó sẽ là đại biểu riêng của mình và nói với đại biểu riêng của mình để gọi một khối bạn vượt qua trong

+0

Câu trả lời của bạn cũng giúp tôi rất nhiều, xe tăng –

Các vấn đề liên quan