2017-07-27 48 views
0

我有一個模型類使用領域來執行CRUD操作。如何防止不正確的線程領域訪問

我想在串行隊列上執行所有操作。

我已聲明的隊列屬性:

@property (nonatomic, strong) dispatch_queue_t realmQueue; 
@property (strong,nonatomic) RLMRealm *secureRealm; 

,我用單初始化隊列:

+ (id)sharedInstance { 
    static ActivityManager *sharedManager = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sharedManager = [[self alloc] init]; 

    }); 

    return sharedManager; 
} 

-(id)init{ 
    self.realmQueue = dispatch_queue_create("realm_activity", DISPATCH_QUEUE_SERIAL); 
    dispatch_async(self.realmQueue, ^{ 
    _secureRealm = [RLMRealm defaultRealm]; 
    }); 
    return self; 
} 

-(NSArray *)getDataOnSettingFilter{ 

    NSMutableArray *activityArr = [NSMutableArray array]; 
    NSString *filterSQL = //; 

    RLMResults *activityResults = [[[self getActivitySource]activities] objectsWhere:filterSQL]; 

    dispatch_async(self.realmQueue, ^{ 
     [_secureRealm beginWriteTransaction]; 

     for (RealmActivity *activity in activityResults){ 

     //modify realm properties 

     [_secureRealm addOrUpdateObject:activity]; 
     [activityArr addObject:activity]; 
    } 
     [_secureRealm commitWriteTransaction]; 
    }); 
    return [activityArr copy]; 
} 

和當我打電話使用上述方法:

[[ActivityManager sharedInstance]getDataOnSettingFilter] 

我得到一個崩潰,說領域是從一個不正確的線程訪問的。

我在這裏做錯了什麼。我如何檢查我是否總是在正確的線程上調用領域?

回答

1

您不應該存儲對單例Realm實例的引用,因爲您無法確保始終可以從同一個線程訪問它。由於Realm文檔狀態,RLMRealm,RLMResults,或RLMArray的

實例或託管實例RLMObject的 是線程限制,這意味着他們只能在他們所創建的線程上使用 ,否則一個例外是 拋出

這意味着你不應該嘗試使用RLMRealm *realm = [RLMRealm defaultRealm];創建一個單獨Realm實例,並且不是試圖訪問無處不在,從您的應用程序。

你可以嘗試使用RLMThreadSafeReference創建到可以線程之間安全地共享Realm對象的引用,但由於文檔狀態的Passing instances across threads一部分,這些引用只能使用一次,所以它們不能被重用爲單身。

然而,沒有必要對這樣的事情,因爲每次調用RLMRealm *realm = [RLMRealm defaultRealm];時,框架會自動創建一個參考您的當前線程你是讓你只要安全地與它進行交互,你不要在使用Realm不要離開那條線。

在一個線程安全的方式使用Realm最好的方法是創建每次線程之間移動,並需要訪問你的Realm一次使用RLMRealm *realm = [RLMRealm defaultRealm];新的引用您的Realm。這樣你可以確保你永遠不會得到不正確的線程異常。

+2

謝謝,我發現另一個原因,在領域隊列上創建的領域對象在cellForRow方法的主線程上訪問,這種情況也導致我崩潰。我確保使用領域的單元定製在領域隊列上運行! –

相關問題