簡體   English   中英

Mac OS X,使用NSMutableArray導致Objective-C崩潰

[英]Mac OS X, Objective-C crash with NSMutableArray

環境:Mac OS 10.8.5,XCode 5.1.1

問題:崩潰的obj_msgsendaddObject消息到NSMutableArray

免責聲明:我是Objective-C的新手,所以這可能是一個明顯的錯誤。 但這很神秘。

細節:

盡管有問題的確切表現與整個應用程序有所不同,但我已經能夠將問題簡化為一個小的測試用例。

這是@interface:

@interface ObjCQueue : NSObject
+ (void) push: (NSString *)calEvent;
+ (NSString *) pop;
@end

這是Objective-C類的實現。

#import <Foundation/Foundation.h>
#include "ObjcQueue.h"

NSMutableArray *qArray;

@implementation ObjCQueue
{

}

+ (void) init
{
    qArray =  [[NSMutableArray alloc] init]; 
    //    NSLog(@"(init)qArray class is: %@\n", NSStringFromClass([qArray class]));
}

+ (void) push:(NSString *)calEvent
{
    [qArray addObject:calEvent];
} 

+ (NSString *) pop
{
    // This will return nil if there's no first object
    NSString *retEvent = [qArray objectAtIndex:0];
    // Don't delete the front of the queue if nothing is there
    if (retEvent != nil)
        [qArray removeObjectAtIndex:0];

    return retEvent;
}
@end

而main.m這樣做:

int main(int argc, const char * argv[])
{
    @autoreleasepool {     
        [ObjCQueue init];
        [ObjCQueue push:@"Pushed thing"];
        NSLog(@"Popped: %@\n", [ObjCQueue pop]);
    }
    return 0;
}

目前,讓我們忽略我怎么做是完全錯誤的可能性(我們將繼續討論)。

如果我按原樣運行此代碼,那么objc_msgSend會崩潰,該崩潰由[ObjCQueue push:]發送的addObject消息調用

神秘的部分是,如果我取消注釋[ObjCQueue init]NSLog調用,一切都會正常運行。

在較大的應用程序中,我看到了另一個問題。 該失敗也發生在push方法中,除了運行時錯誤外,我說addObject是無效的選擇器。 在這種情況下,當我檢查qArray的類型時,它具有NSDictionary的類型(這是從內存中qArray的,並不是完全按照這種方式拼寫的),而不是NSMutableArray 另外,在較大的應用程序中,在init方法中添加NSLog調用可使所有操作順利進行。

在這個較小的示例中, qArray的類型始終顯示為NSMutableArray

類似問題的其他答案中,這意味着與qArray對應的對象將被覆蓋和/或過早釋放。 我看不到這怎么發生,因為它是全局的,並且ObjCQueue僅具有類方法,並且沒有創建它的實例。 [ObjCQueue init]僅被調用一次。

另一位數據:在這種較小的情況下, qArray的顯示位置不同(在調試器中)。

init中,如果崩潰,則qArray獲得其值后,調試器將立即顯示:

Printing description of qArray:
<__NSArrayM 0x10010a680>(
)

但是在push ,就在調用addObject方法之前,調試器顯示:

Printing description of qArray:
(NSMutableArray *) qArray = 0x000000010010a680

值是相同的,但是類型有點不同(也許)。 沒有崩潰的情況下,兩種情況下的顯示都是相同的(它們都與第一個顯示相同)

這可能不是初始化qArray的最佳方法(或者可能是公然的錯誤方法),我可以接受。 但是, 為什么增加NSLog調用后行為會發生變化?

任何幫助/見解將不勝感激。

-Eric

PS這是XCode項目: 錯誤測試

問題是因為ARC在調用push之前釋放了qArray ,所以您正在調用已經釋放的對象。 解決此問題的一個好方法是將您的類更改為實際實例,或者創建一個單例,以便ARC知道保留數組,而不僅僅是在初始化后立即釋放它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM