Tôi nhận thấy rằng bạn đang sử dụng dlopen
, không phải CFBundle
hoặc NSBundle
. Tuy nhiên, hướng dẫn Code Loading Programming Topics nói điều này:
Trong các ứng dụng Cocoa, bạn không nên sử dụng CFBundle
thói quen để nạp và xả mã thực thi, vì CFBundle
không natively hỗ trợ thời gian chạy Objective-C. NSBundle
tải đúng các ký hiệu Objective-C vào hệ thống thời gian chạy, nhưng không có cách nào để dỡ các gói Cocoa một khi được tải do giới hạn thời gian chạy.
và điều này:
Do giới hạn trong hệ thống runtime Objective-C, NSBundle
không thể dỡ bỏ mã thực thi.
Điều này làm cho tôi nghi ngờ rằng khi bạn tải thư viện của bạn, nó tự đăng ký với thời gian chạy Objective-C, và thời gian chạy gọi dlopen
trên thư viện một lần nữa (hoặc bằng cách nào đó làm tăng của thư viện số tài liệu tham khảo).
Tôi đã tìm kiếm mã nguồn runtime Objective-C và thấy this:
// dylibs are not allowed to unload
// ...except those with image_info and nothing else (5359412)
if (result->mhdr->filetype == MH_DYLIB && _hasObjcContents(result)) {
dlopen(result->os.dl_info.dli_fname, RTLD_NOLOAD);
}
Vì vậy, có, thời gian chạy Objective-C được gọi dlopen
vào thư viện của bạn đặc biệt để ngăn ngừa nó khỏi bị bốc dỡ. Nếu bạn lừa dối và gọi dlclose
hai lần, bạn sẽ mong đợi những điều xấu xảy ra.
Nguồn
2012-01-09 19:08:14
Bạn có chắc chắn rằng thư viện của bạn không phải là 'dlopen'-ed hai lần theo một cách ẩn? Hoặc có thể là lỗi-ví dụ bộ nhớ bị rò rỉ- là ghi đè bộ nhớ gần xử lý 'dlopen'-ed? –
dlopen giữ một số tham chiếu về việc xử lý thư viện. Nếu dlopen được thực hiện hai lần, nó sẽ yêu cầu hai dlclose() để dỡ bỏ thư viện. Có thể thư viện động được yêu cầu nếu bạn bao gồm mã obj-C không? Trong trường hợp này dlopen đầu tiên có thể được thực hiện khi bạn chạy chương trình của bạn – Finslicer
Có Tôi chắc chắn rằng nó không được mở hai lần. Bạn có thể thử một chương trình đơn giản trong chính với dlopen theo sau là dlclose với thư viện động có mã c mục tiêu. – MacGeek