diff --git a/src/common/IOModesController.cpp b/src/common/IOModesController.cpp
index 4fa29502..88378c10 100644
--- a/src/common/IOModesController.cpp
+++ b/src/common/IOModesController.cpp
@@ -77,16 +77,12 @@ bool IOModesController::prepareForWriting()
 
 bool IOModesController::allChangesComitted()
 {
-    // Get a list of available write changes
-    CutterJson changes = Core()->cmdj("wcj");
-
-    // Check if there is a change which isn't written to the file
-    for (CutterJson changeObject : changes) {
-        if (!changeObject["written"].toBool()) {
+    RzCoreLocked core(Core());
+    for (auto c : CutterPVector<RzIOCache>(&core->io->cache)) {
+        if (!c->written) {
             return false;
         }
     }
-
     return true;
 }
 
diff --git a/src/core/CutterCommon.h b/src/core/CutterCommon.h
index 3cbc1941..6d6f7e7a 100644
--- a/src/core/CutterCommon.h
+++ b/src/core/CutterCommon.h
@@ -25,6 +25,32 @@
              (char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size);                     \
              it = (type *)((char *)it + (vec)->elem_size))
 
+template<typename T> class CutterPVector
+{
+private:
+    const RzPVector * const vec;
+
+public:
+    class iterator : public std::iterator<std::input_iterator_tag, T *>
+    {
+    private:
+        T **p;
+
+    public:
+        iterator(T **p) : p(p) {}
+        iterator(const iterator &o) : p(o.p) {}
+        iterator &operator++() { p++; return *this; }
+        iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
+        bool operator==(const iterator &rhs) const {return p == rhs.p;}
+        bool operator!=(const iterator &rhs) const {return p != rhs.p;}
+        T *operator*() { return *p; }
+    };
+
+    CutterPVector(const RzPVector *vec) : vec(vec) {}
+    iterator begin() const { return iterator(reinterpret_cast<T **>(vec->v.a)); }
+    iterator end() const { return iterator(reinterpret_cast<T **>(vec->v.a) + vec->v.len); }
+};
+
 // Global information for Cutter
 #define APPNAME "Cutter"