0

I have a singleton that contains variable called currentBusiness

I wired the currentBusiness property like this

-(Business *) currentBusiness
{
    if ([[NSThread currentThread] isMainThread])
    {
        DLog(@"I am a main thread");
    }
    else
    {
        assert (false);
        DLog(@"I am not a main thread");
    }

    CLog(@"_currentBusiness %@ withObjectID: %@", _currentBusiness, _currentBusiness.objectID);

    if (IsEmpty(_currentBusiness))
    {
        //assert(false);
    }
    if (_currentBusiness.isFault)
    {
        assert(false); //This is reached
    }
    return _currentBusiness;
}

In addition, I put a category for business to trap will turn fault

- (void)willTurnIntoFault
{
    if ([[NSThread currentThread] isMainThread])
    {
        CLog(@"Faulting: %@", self); //called sometimes and during time of interest never called
        if (self == [BNUtilitiesQuick currentBusiness])
        {
            CLog(@"Current Business is Faulting");//never called
        }
    }

    [super willTurnIntoFault];
}

So, at first everything is fine. As expected [BNUtilities currentBusiness] supply the viewcontroller with necessary information. However, at random (though almost certain) location, if I change view, say I want to activate call (with simple code). Suddenly

    if (_currentBusiness.isFault)
    {
        assert(false); //This is reached
    }

There is absolutely nothing that I know that would change _currentBusiness. The underlying business is not deleted.

I also put tripwire on

-(void) setCurrentBusiness:(Business *)currentBusiness
{
    if ([[NSThread currentThread] isMainThread])
    {
        DLog(@"I am a main thread");
    }
    else
    {
        assert (false);
        DLog(@"I am not a main thread");
    }
    _currentBusiness = currentBusiness;
}

and notice it's not reached. So _currentBusiness, out of nowhere suddenly become fault

This is the "normal" content of _currentBusiness

2012-05-21 15:42:24.952 BadgerNew[2292:17003] <0x87909a0 UtilitiesQuick.m:(69)> _currentBusiness <Business: 0x96a8980> (entity: Business; id: 0x9683b30 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15> ; data: {
    Aliases = "<relationship fault: 0x96b8540 'Aliases'>";
    Bookmark = 0;
    Building = "0x9683b30 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15>";
    City = "0x9694880 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/City/p2>";
    Distance = "689.0068307560858";
    DistanceGrouping = "0x96b9b90 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/DistanceGrouping/p890>";
    Districts =     (
        "0x92a6450 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/District/p4>"
    );
    Email = nil;
    ID = "universitas-indonusa-esa-unggul__-6.19_106.78";
    Images =     (
        "0x93edb50 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Image/p20>"
    );
    InBuildingAddress = nil;
    LatitudeLongitude = "0x96bd6a0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/LatitudeLongitude/p15>";
    Like = 0;
    OpeningHour = nil;
    PeopleCount = 295;
    Phones =     (
        "0x92dcbf0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Phone/p4>"
    );
    Price = 0;
    Promotions = "<relationship fault: 0x9693480 'Promotions'>";
    Rating = "0x96a0f00 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Rating/p15>";
    RatingGroup = "0x9682bd0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/RatingGroup/p15>";
    Reviews =     (
    );
    Street = "Jl. Arjuna Utara";
    Tags =     (
        "0x92b5c10 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Tag/p12>"
    );
    Tenants = "<relationship fault: 0x96e6fd0 'Tenants'>";
    TimeStamp = nil;
    Title = "Universitas Indonusa Esa Unggul";
    URLs = "<relationship fault: 0x968d930 'URLs'>";
    Website = nil;
    Zip = 11510;
    checkIn = nil;
    pinAndLineNumber = 2;
    timeLike = nil;
    updated = 1;
})

When it's faulted and break at

    if (_currentBusiness.isFault)
    {
        assert(false); //This is reached
    }

This is the result:

2012-05-21 15:42:36.782 BadgerNew[2292:17003] <0x87909a0 UtilitiesQuick.m:(69)> _currentBusiness <Business: 0x96a8980> (entity: Business; id: 0x9683b30 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15> ; data: <fault>)

So yea I do some po and

(lldb) po [_currentBusiness objectID]
error: warning: couldn't get required object pointer (substituting NULL): Couldn't load 'self' because its type is unknown
warning: couldn't get object pointer (substituting NULL): Couldn't load '_cmd' because its type is unknown
Execution was interrupted, reason: Attempted to dereference an invalid pointer..
The process has been returned to the state before execution.

It's as if the content of _currentBusiness is changed. current_Business is still there. It still have the same address.

What the hell is going on?

And no, it's not just fault. It's a fault it can't get out.

So I added further tripwire

-(Business *) currentBusiness
{
    if ([[NSThread currentThread] isMainThread])
    {
        DLog(@"I am a main thread");
    }
    else
    {
        assert (false);
        DLog(@"I am not a main thread");
    }

    CLog(@"_currentBusiness %@ withObjectID: %@", _currentBusiness, _currentBusiness.objectID); //add ObjectID

    if (IsEmpty(_currentBusiness))
    {
        //assert(false);
    }
    if (_currentBusiness.isFault)
    {
        CLog(@"_currentBusiness.Title %@", _currentBusiness.Title); //Try to unfault
        assert(false);
    }
    return _currentBusiness;
}

I bet I can't unfault.

So this is the result:

2012-05-21 16:08:37.950 BadgerNew[2625:17003] <0x9510470 UtilitiesQuick.m:(69)> _currentBusiness <Business: 0x9589410> (entity: Business; id: 0x95889d0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15> ; data: {
    Aliases = "<relationship fault: 0x953cdf0 'Aliases'>";
    Bookmark = 0;
    Building = "0x95889d0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15>";
    City = "0x958dde0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/City/p2>";
    Distance = "689.0068307560858";
    DistanceGrouping = "0x9582f40 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/DistanceGrouping/p924>";
    Districts =     (
        "0x874b0d0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/District/p4>"
    );
    Email = nil;
    ID = "universitas-indonusa-esa-unggul__-6.19_106.78";
    Images =     (
        "0x95c4be0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Image/p20>"
    );
    InBuildingAddress = nil;
    LatitudeLongitude = "0x958f430 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/LatitudeLongitude/p15>";
    Like = 0;
    OpeningHour = nil;
    PeopleCount = 295;
    Phones =     (
        "0x9237680 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Phone/p4>"
    );
    Price = 0;
    Promotions = "<relationship fault: 0x954bae0 'Promotions'>";
    Rating = "0x9584b50 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Rating/p15>";
    RatingGroup = "0x9586970 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/RatingGroup/p15>";
    Reviews =     (
    );
    Street = "Jl. Arjuna Utara";
    Tags =     (
        "0x8769120 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Tag/p12>"
    );
    Tenants = "<relationship fault: 0x955fd90 'Tenants'>";
    TimeStamp = nil;
    Title = "Universitas Indonusa Esa Unggul";
    URLs = "<relationship fault: 0x955f620 'URLs'>";
    Website = nil;
    Zip = 11510;
    checkIn = nil;
    pinAndLineNumber = 2;
    timeLike = nil;
    updated = 1;
}) withObjectID: 0x95889d0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15>

and then

2012-05-21 16:08:42.797 BadgerNew[2625:17003] <0x9510470 UtilitiesQuick.m:(69)> _currentBusiness <Business: 0x9589410> (entity: Business; id: 0x95889d0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15> ; data: <fault>) withObjectID: 0x95889d0 <x-coredata://3993C454-9EE9-4EDC-B1FD-7073A9CEC194/Business/p15>
2012-05-21 16:08:42.797 BadgerNew[2625:17003] <0x9510470 UtilitiesQuick.m:(77)> _currentBusiness.Title (null)
(lldb) po [_currentBusiness objectID]
error: warning: couldn't get required object pointer (substituting NULL): Couldn't load 'self' because its type is unknown
warning: couldn't get object pointer (substituting NULL): Couldn't load '_cmd' because its type is unknown
Execution was interrupted, reason: Attempted to dereference an invalid pointer..
The process has been returned to the state before execution.

So the address of _currentBusiness doesn't change. The objectID doesn't change. Somehow it becomes fault. Also calling _currentBusiness.Title results in (null)

This doesn't seem to happen before ARC update though I am not sure if the ARC caused it.

Cœur
  • 37,241
  • 25
  • 195
  • 267
user4951
  • 32,206
  • 53
  • 172
  • 282

1 Answers1

0

I found out the problem already. The managed object context get recreated everytime it's called. Stupid mistake. I'll put this as an answer so if somebody has the same issue they should look this up first.

Managed Object Contexts are usually lazy loaded.

user4951
  • 32,206
  • 53
  • 172
  • 282