8

Vấn đề

Câu hỏi này có vẻ hơi dài, vì tôi thực sự loạng choạng bởi điều này."bộ chọn không được nhận dạng được gửi tới lớp" khi gọi phương thức danh mục từ thư viện

Tôi hiện đang làm việc một số library nên tự động phân tích cú pháp tài liệu XML. Nhưng tôi đang gặp một vấn đề bây giờ kiểm tra thư viện lần đầu tiên.

Tôi có một lớp thư viện có tên là CSXDocumentLayout đại diện cho bố cục của tài liệu. Lớp này chứa phương thức riêng tư - (NSError *)readLayoutDocument:(NSString *)fpath được gọi từ phương thức init.

/* MARK: Reading in Layouts */ 
- (NSError *)readLayoutDocument:(NSString *)fpath { 
    CSXDocumentLayout *layout; 
    CSXXMLParser *parser; 
    BOOL state; 

    layout = [CSXDocumentLayout layoutDocumentLayout]; 

    parser = [[CSXXMLParser alloc] initWithDocumentLayouts: 
       [NSArray arrayWithObject:layout]]; 
    parser.file = fpath; 

    state = [parser parse]; 

    if(state == NO || parser.error != nil) { 
     return parser.error; 
    } 
    return nil; 
} 

Phương pháp này sẽ đọc trong tài liệu XML thể hiện bố cục của tài liệu XML khác. Nó được phân tích bởi lớp CSXXMLParser, mà tôi muốn kiểm tra.

Tôi tạo một đối tượng thể hiện tài liệu bố cục với +[CSXDocumentLayout layoutDocumentLayout]. Phương pháp này được triển khai trong danh mục CSXDocumentLayout (CSXLayoutObject).

Dưới đây là tập tin thử nghiệm của tôi:

#import <Foundation/Foundation.h> 
#import <CeasyXML.h> 

int main(int argc, const char **argv) { 
    NSAutoreleasePool *pool = [NSAutoreleasePool new]; 

    NSString *file; 

    file = [NSString stringWithUTF8String:__FILE__]; 
    file = [file stringByDeletingLastPathComponent]; 
    file = [file stringByAppendingPathComponent:@"Layout.xml"]; 

    CSXDocumentLayout *layout; 
    NSError *error; 

    layout = [[CSXDocumentLayout alloc] initWithLayoutDocument:file 
                 error:&error]; 
    if(layout == nil) { 
     NSLog(@"Could not create layout: %@", error); 
     exit(0); 
    } 

    NSLog(@"Layout:\n%@", layout); 

    [pool release]; 
    return 0; 
} 

Tập tin này biên dịch để thực thi riêng biệt liên quan đến thư viện tĩnh của tôi libceasyxml.a. Tất cả mọi thứ biên dịch tốt mà không có bất kỳ cảnh báo nào.

Nhưng khi tôi chạy nó tôi nhận được một selector không được công nhận gửi đến lớp ngoại lệ:

2012-05-02 16:59:47.620 TestApp[1887:a0f] +[CSXDocumentLayout layoutDocumentLayout]: unrecognized selector sent to class 0x1000064c8 
2012-05-02 16:59:47.791 TestApp[1887:a0f] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[CSXDocumentLayout layoutDocumentLayout]: unrecognized selector sent to class 0x1000064c8' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x00007fff83e47784 __exceptionPreprocess + 180 
    1 libobjc.A.dylib      0x00007fff84604f03 objc_exception_throw + 45 
    2 CoreFoundation      0x00007fff83ea11a0 __CFFullMethodName + 0 
    3 CoreFoundation      0x00007fff83e198ef ___forwarding___ + 751 
    4 CoreFoundation      0x00007fff83e15a38 _CF_forwarding_prep_0 + 232 
    5 TestApp        0x0000000100001512 -[CSXDocumentLayout(Private) readLayoutDocument:] + 49 
    6 TestApp        0x00000001000010d4 -[CSXDocumentLayout initWithLayoutDocument:error:] + 96 
    7 TestApp        0x0000000100001017 main + 179 
    8 TestApp        0x0000000100000f5c start + 52 
    9 ???         0x0000000000000001 0x0 + 1 
) 

Tôi thấy nó rất đáng lo ngại mà tôi không thể gọi phương thức lớp +[CSXDocumentLayout(CSXLayoutObject) layoutDocumentLayout], mặc dù tôi có thể gọi cả hai -[CSXDocumentLayout initWithLayoutDocument:error:], và -[CSXDocumentLayout(Private) readLayoutDocument:].

Nghiên cứu

Tôi đã kiểm tra nếu phương pháp này được định nghĩa trong các tập tin đầu ra bằng cách chạy nm file và nó là, cũng một phần là:

Trong libceasyxml.a, nó được định nghĩa (nm libceasyxml.a)

... 
libceasyxml.a(CSXDocumentLayout+CSXLayoutObject.o): 
0000000000000100 t +[CSXDocumentLayout(CSXLayoutObject) classAttributeLayout] 
00000000000020e0 s +[CSXDocumentLayout(CSXLayoutObject) classAttributeLayout].eh 
000000000000056b t +[CSXDocumentLayout(CSXLayoutObject) documentElementLayout] 
0000000000002180 s +[CSXDocumentLayout(CSXLayoutObject) documentElementLayout].eh 
0000000000000402 t +[CSXDocumentLayout(CSXLayoutObject) layoutDocumentLayout] 
0000000000002148 s +[CSXDocumentLayout(CSXLayoutObject) layoutDocumentLayout].eh 
0000000000000200 t +[CSXDocumentLayout(CSXLayoutObject) layoutElementLayout] 
0000000000002110 s +[CSXDocumentLayout(CSXLayoutObject) layoutElementLayout].eh 
0000000000000000 t +[CSXDocumentLayout(CSXLayoutObject) nameAttributeLayout] 
00000000000020b0 s +[CSXDocumentLayout(CSXLayoutObject) nameAttributeLayout].eh 
0000000000002098 s EH_frame1 
0000000000001c49 s LC0 
... 

Trong TestApp, nó không được định nghĩa (nm TestApp), thực sự tôi không thể tìm thấy bất kỳ phương pháp nào với tên danh mục CSXLayoutObject.

... 
0000000100001271 t -[CSXDocumentLayout setDocumentClassString:] 
00000001000013a8 t -[CSXDocumentLayout setElements:] 
0000000100001490 t -[CSXDocumentLayout setName:] 
00000001000014db t -[CSXDocumentLayout(Private) readLayoutDocument:] 
0000000100004060 t -[CSXElementList dealloc] 
00000001000040b0 t -[CSXElementList elements] 
... 

Trả lời

26

Tôi nghi ngờ bạn đã gặp phải sự cố đã biết là categories embedded in static libraries.

Nếu tôi đúng, hãy cố gắng biên dịch với cờ liên kết -ObjC (và nếu điều đó không đủ, cũng -all_load) và sự cố của bạn sẽ biến mất.

+0

Làm việc hoàn hảo, cảm ơn bạn. – v1Axvw

+3

Đối với người đọc trong tương lai, tôi phải thêm cờ vào 'các cờ liên kết khác' trong menu 'liên kết'. (ios 6.1, xcode 4.3) – Kevin

+0

Trong khi câu trả lời này thường là giải pháp, giải pháp khác, do Ace cung cấp, là một giải pháp miễn phí tuyệt vời và bao gồm một trường hợp khác có thể xảy ra. –

3

Mặc dù câu trả lời đã được chọn, tôi muốn giải pháp cho vấn đề của tôi ở đây, đơn giản như có thể. Hãy chắc chắn kiểm tra xem lớp của bạn có được kiểm tra chính xác trong trường Target Membership trong ngăn File Inspector hay không.Nếu bạn không làm như vậy thì nó chỉ tự nhiên nhận được lỗi unrecognized selector sent to class.

+0

Đó là nó cho tôi! Cảm ơn bạn loại người lạ! –

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