2012-01-06 23 views
6

Cho tôi có một trình chỉ định kiểu như được trả về bởi method_copyReturnType(). Trong thời gian chạy GNU được phân phối với GCC, có nhiều phương pháp khác nhau để làm việc với một trình định kiểu như vậy như objc_sizeof_type(), objc_alignof_type() và các phương thức khác.Cách diễn giải thông số loại khách quan-c (ví dụ: được trả về bởi method_copyReturnType())?

Khi sử dụng thời gian chạy của Apple, không có phương pháp nào như vậy.

Làm cách nào để diễn giải chuỗi chỉ định loại (ví dụ: lấy kích thước của một loại) bằng cách sử dụng thời gian chạy của Apple mà không cần thực hiện chuyển đổi if/else hoặc case cho chính tôi?

[cập nhật]

Tôi không thể sử dụng Apple Foundation.

Trả lời

2

afaik, bạn sẽ cần phải nướng thông tin đó vào nhị phân của mình. chỉ cần tạo một hàm trả về sizeof và alignof trong một cấu trúc, hỗ trợ các kiểu mà bạn phải hỗ trợ, sau đó gọi hàm đó (hoặc phương thức lớp) cho thông tin.

Chương trình dưới đây cho bạn biết rằng nhiều nguyên thủy chỉ là một ký tự. Vì vậy, phần lớn việc thực hiện của hàm có thể là một công tắc.

static void test(SEL sel) { 
    Method method = class_getInstanceMethod([NSString class], sel); 

    const char* const type = method_copyReturnType(method); 

    printf("%s : %s\n", NSStringFromSelector(sel).UTF8String, type); 

    free((void*)type); 
} 

int main(int argc, char *argv[]) { 
    @autoreleasepool { 

     test(@selector(init)); 
     test(@selector(superclass)); 
     test(@selector(isEqual:)); 
     test(@selector(length)); 

     return 0; 
    } 
} 

và sau đó bạn có thể sử dụng như là một điểm khởi đầu:

typedef struct t_pair_alignof_sizeof { 
    size_t align; 
    size_t size; 
} t_pair_alignof_sizeof; 

static t_pair_alignof_sizeof MakeAlignOfSizeOf(size_t align, size_t size) { 
    t_pair_alignof_sizeof ret = {align, size}; 
    return ret; 
} 

static t_pair_alignof_sizeof test2(SEL sel) { 
    Method method = class_getInstanceMethod([NSString class], sel); 
    const char* const type = method_copyReturnType(method); 
    const size_t length = strlen(type); 

    if (1U == length) { 
     switch (type[0]) { 
      case '@' : 
       return MakeAlignOfSizeOf(__alignof__(id), sizeof(id)); 
      case '#' : 
       return MakeAlignOfSizeOf(__alignof__(Class), sizeof(Class)); 
      case 'c' : 
       return MakeAlignOfSizeOf(__alignof__(signed char), sizeof(signed char)); 
      ... 
+0

Vì vậy, câu trả lời là: Không có cách nào để thực hiện việc này mà không tự mình triển khai. Chính xác? –

+0

@Tilo Tôi đã thực hiện một số điều ngớ ngẩn với thời gian chạy - không có giải pháp miễn phí mà tôi biết, nhưng giải pháp trong câu trả lời của tôi có thể được triển khai khá dễ dàng nếu bạn biết các loại bạn phải hỗ trợ. Tất nhiên, bạn cũng có thể chờ xem liệu bạn có câu trả lời thích hợp hơn hay không. – justin

+0

@Tilo - đã thêm bản trình diễn cho số – justin

5

Tôi tin rằng bạn đang tìm kiếm NSGetSizeAndAlignment:

có được kích thước thực tế và kích thước phù hợp của một loại được mã hóa.

const char * NSGetSizeAndAlignment (
    const char *typePtr, 
    NSUInteger *sizep, 
    NSUInteger *alignp 
);

Thảo luận
có được kích thước thực tế và kích thước phù hợp của các loại dữ liệu đầu tiên đại diện bởi typePtr và trả về một con trỏ đến vị trí của các kiểu dữ liệu tiếp theo trong typePtr.

Đây là chức năng Foundation, không phải là một phần của thời gian chạy cơ sở, có thể là lý do bạn không tìm thấy nó.

CẬP NHẬT: Mặc dù ban đầu bạn không đề cập rằng bạn đang sử dụng Cocotron, nó cũng có sẵn ở đó. Bạn có thể tìm thấy nó trong Cocotron's Foundation, trong NSObjCRuntime.m. Rõ ràng, điều này tốt hơn nhiều so với việc cuộn của riêng bạn, vì bạn có thể tin tưởng nó luôn xử lý đúng chuỗi được tạo bởi thời gian chạy của chính nó trong trường hợp không chắc rằng các ký tự mã hóa sẽ thay đổi.

Vì một số lý do, tuy nhiên, nó không thể xử lý các phần tử chữ số của chuỗi ký tự phương thức (có lẽ là có liên quan đến số dời trong bộ nhớ). This improved version, by Mike Ash sẽ làm như vậy:

static const char *SizeAndAlignment(const char *str, NSUInteger *sizep, NSUInteger *alignp, int *len) 
{ 
    const char *out = NSGetSizeAndAlignment(str, sizep, alignp); 
    if(len) 
     *len = out - str; 
    while(isdigit(*out)) 
     out++; 
    return out; 
} 
+0

+1 tìm kiếm tốt, Josh – justin

+0

Vấn đề là, tôi không có quyền truy cập chung vào Apple Foundation vì nó chỉ tồn tại đối với các sản phẩm của Apple :). Dự án tôi đang làm là Cocotron (một giải pháp thay thế cho Quỹ). Vì vậy, tôi không thể sử dụng phương pháp Foundation. –

+0

@Tilo: Khung bạn đang sử dụng là ** điều kiện khá lớn ** mà có lẽ bạn nên đưa vào câu hỏi của mình để bắt đầu. Tuy nhiên, chức năng tương tự có sẵn trong Cococtron. Xem chỉnh sửa của tôi. –

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