2017-04-06 26 views
0

不時我的用戶發現這個錯誤:抓NSMallocExceptioni使用SWIFT

myapp(7383,0x1a1471000) malloc: * mach_vm_map(size=67125248) failed (error code=3) error: can't allocate region set a breakpoint in malloc_error_break to debug 2017-04-06 20:33:58.152 myapp[7383:3724816] Terminating app due to uncaught exception 'NSMallocException', reason: ' NSAllocateObject(): attempt to allocate object of class 'IOSByteArray' failed' * First throw call stack: (0x183386db0 0x1829ebf80 0x183386cf8 0x183c6b34c 0x10076e6e4 0x10097d3ec 0x10097e35c 0x100977dd4 0x100977bd8 0x100978ff8 0x10096c950 0x10099685c 0x100997360 0x100979ca4 0x100976dcc 0x1002ec30c 0x100332fe4 0x100332e18 0x1003740c4 0x1004070f8 0x1004064ac 0x1021089b0 0x10210806c 0x1021089b0 0x102107710 0x1004072d8 0x1021087ec 0x1004071b0 0x102126bbc 0x10207b2d8 0x10207b374 0x188613dc4 0x1886d17d4 0x18878f0c8 0x18879ca80 0x1884ce5a4 0x18333c728 0x18333a4cc 0x18333a8fc 0x183264c50 0x184b4c088 0x188546088 0x100382a60 0x182e028b8) libc++abi.dylib: terminating with uncaught exception of type NSException

的問題是,我無法找到錯誤的調用堆棧。 我正在使用j2objc應用程序將XZ java lib移植到objc庫中。 所以,我可以使用這個庫,但我無法捕捉到這個錯誤。

谷歌Analytics(分析)幫助我,並顯示該行:

"&exd" = "NSMallocException\nTrace:\n\nNSAllocateObject\nIOSByteArray_NewArray\nOrgTukaaniXzLzLZDecoder_initWithInt_withByteArray_\nnew_OrgTukaaniXzLzLZDeco";

因此,似有發生錯誤:

void OrgTukaaniXzLzLZDecoder_initWithInt_withByteArray_(OrgTukaaniXzLzLZDecoder *self, jint var1, IOSByteArray *var2) { 
    NSObject_init(self); 
     self->start_ = 0; 
     self->pos_ = 0; 
     self->full_ = 0; 
     self->limit_ = 0; 
     self->pendingLen_ = 0; 
     self->pendingDist_ = 0; 
     JreStrongAssignAndConsume(&self->buf_, [IOSByteArray newArrayWithLength:var1]); 
     if (var2 != nil) { 
      self->pos_ = JavaLangMath_minWithInt_withInt_(var2->size_, var1); 
      self->full_ = self->pos_; 
      self->start_ = self->pos_; 
      JavaLangSystem_arraycopyWithId_withInt_withId_withInt_withInt_(var2, var2->size_ - self->pos_, self->buf_, 0, self->pos_); 
     } 
} 

但是,使用SWIFT我找不到這個錯誤:

do { 
// ............ 
let inxz:OrgTukaaniXzXZInputStream = try OrgTukaaniXzXZInputStream(javaIoInputStream:in_) 
// .......... 
} catch { 
print(error) 
} 

請幫幫我

+0

跑掉j2objc – Sulthan

+0

@Sulthan解釋plz – Vyacheslav

+0

看來這是https://github.com/wikimedia/openzim/blob/master/zimreader-java/src/org/tukaani/xz/lz的翻譯版本/ LZDecoder.java只能從'LZMA2InputStream.java'調用我已經查看了代碼,並且沒有辦法如何導致內存異常。無論是內存處理翻譯嚴重,導致內存泄漏(使用儀器泄漏檢測)或內部檢查字典大小翻譯嚴重。這兩種可能性意味着翻譯不正確。爲什麼不直接使用C版本? – Sulthan

回答

1

Swift的try/catch完全獨立於ObjC這樣的異常。這些只能使用@try@catch與ObjC聯繫。在Swift中是不可能的。

也就是說,ObjC通常不是異常安全的。您必須非常小心地使用它們,並且在幾乎所有情況下,異常後的正確行爲是使程序崩潰。在這種情況下,只需一次調用橋接函數,就可以有效地捕捉和處理,但正確執行操作是相當微妙的技巧,如果可以避免,不建議使用。

幾乎可以肯定這個錯誤的原因是你試圖分配太大的東西。我沒有試圖去捕捉異常,而是研究爲什麼這個對象是如此之大,並解決這個問題。特別是,我想看看var1有多大,並確保它在合理的範圍內。還要確保它不是負面的。您使用jint的事實表明您可能會看到與您的整數類型不匹配,我絕對希望這會導致此類崩潰。

+0

我使用Eureka lib與內部回調的展開/摺疊內容。所以,用戶嘗試多次解碼一個小的xz數據。沒有內存泄漏。我無法理解或理解這個問題。不管怎樣,謝謝。看來我必須手動編輯轉換代碼。 – Vyacheslav

1

感謝@蘇丹。他給了我一個使用XZ純C庫而不是Java> ObjC lib的想法。現在這個崩潰不存在。看來j2obc是奇怪的框架,但它有罕見的不可捕捉的錯誤。