Category Archives: C/C++/Objective-C

Retain cycle in Parent Child inheritance example

Note: ARC is enabled to demonstrate strong/weak usage of retain cycle

Parent Child example

Parent.h

Parent.m

Child.h

Child.m

main.m

So we have a Parent object that has strong reference to a child Object. Upon initialization, it creates a strong reference to the child object. When we alloc and nil out the object in main, we see the appropriate actions taken:

Result:

2015-09-10 16:28:07.667 RetainCycleEx[37844:1585148] Parent.m (init) – init
2015-09-10 16:28:07.668 RetainCycleEx[37844:1585148] Child.m (init) – init
2015-09-10 16:28:07.669 RetainCycleEx[37844:1585148] Parent.m – I’m dealloc…..my retain count is 0
2015-09-10 16:28:07.669 RetainCycleEx[37844:1585148] Child.m – I’m dealloc…..my retain count is 0

Once we allocate the Parent, it in turn allocates the Child. Once we nil out the Parent, ARC garbage collects Parent object, which calls dealloc. That dealloc will set the Child object to nil, which makes ARC call Child’s dealloc so it can clean up.

Hence, everything is as expected.

Creating the retain cycle

main.m

Say we make the Child object have a strong reference on its parent. Thus, we’ve created a circular retain cycle. When fumu gets niled, the ARC won’t garbage collect it (aka call dealloc on Parent object) because Parent is pointed to by the child. If Parent’s dealloc method do not get called, then its child object won’t get niled, and thus, the Child object will never be cleaned up. Hence this parent and its child is now floating around and ARC will never clean them up because they have a strong reference towards each other.

Result:

2015-09-10 16:36:07.856 RetainCycleEx[38356:1588472] Parent.m (init) – init
2015-09-10 16:36:07.857 RetainCycleEx[38356:1588472] Child.m (init) – init

Where the problem lies
Child.h

The problem is that our Child object’s parent pointer, is a strong reference. If you change it to weak, and run the problem again, then the dealloc gets called.

The reason is because when pointer fumu gets niled, ARC will see NO strong references on Parent, thus, it will assume its safe to garbage collect it.

Result:

2015-09-10 16:46:56.921 RetainCycleEx[39034:1592492] Parent.m (init) – init
2015-09-10 16:46:56.922 RetainCycleEx[39034:1592492] Child.m (init) – init
2015-09-10 16:46:56.922 RetainCycleEx[39034:1592492] Child.m – I’m dealloc…..my retain count is 0
2015-09-10 16:46:56.923 RetainCycleEx[39034:1592492] Parent.m – I’m dealloc…..my retain count is 0

Non Propety example

We can also use __strong and __weak to demonstrate this. Notice that we must be in an ARC environment in order to see the effects of __strong/__weak.

We first create a pointer fumu to a Parent object. Even though no __strong is specified, it is by default __strong. Then we have a weak reference to the same Parent object. we set the fumu to nil.

At this point, even though the reference fumu is niled in the auto varaibles console, you’ll see that strongFumu and weakFumu are pointing to an object with an address. That’s because we still have a strong reference to the Parent object pointing to by strongFumu.

Then we nil out strongFumu and you’ll see both weakFumu and strongFumu both being niled. That’s because the Parent object have 0 strong references on it. Thus ARC garbage collects it and Parent object’s dealloc method gets called.

//3

2015-09-10 17:04:49.289 RetainCycleEx[40294:1601178] Parent.m (init) – init
2015-09-10 17:04:49.290 RetainCycleEx[40294:1601178] Child.m (init) – init

//4

2015-09-10 17:04:49.289 RetainCycleEx[40294:1601178] Parent.m (init) – init
2015-09-10 17:04:49.290 RetainCycleEx[40294:1601178] Child.m (init) – init
2015-09-10 17:04:52.383 RetainCycleEx[40294:1601178] Parent.m – I’m dealloc…
2015-09-10 17:04:52.383 RetainCycleEx[40294:1601178] Child.m – I’m dealloc..

Objective C stack and heap

https://mikeash.com/pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html

Stack
  • The stack is a region of memory which contains storage for local variables, as well as internal temporary values and housekeeping.
  • On a modern system, there is one stack per thread of execution.
  • When a function is called, a stack frame is pushed onto the stack, and function-local data is stored there.
  • When the function returns, its stack frame is destroyed.
Heap

The heap is, essentially, everything else in memory.

  • Memory can be allocated on the heap at any time, and destroyed at any time.
  • You have to explicitly request for memory to be allocated from the heap, and if you aren’t using garbage collection, explicitly free it as well.
  • This is where you store things that need to outlive the current function call. The heap is what you access when you call malloc and free.

Stack vs Heap Objects

Given that, what’s a stack object, and what’s a heap object?

First, we must understand what an object is in general. In Objective-C (and many other languages), an object is simply a contiguous blob of memory with a particular layout.

The precise location of that memory is less important. As long as you have some memory somewhere with the right contents, it’s a working Objective-C object. In Objective-C, objects are usually created on the heap:

NSObject *obj = [[NSObject alloc] init];

The storage for the obj pointer variable itself is on the stack
but the object it points to is in the heap.
In other words, the obj pointer variable is pushed onto the stack. The NSObject object that it points to, is allocated on the heap

The [NSObject alloc] call allocates a chunk of heap memory, and fills it out to match the layout needed for an NSObject.

Using NS Collection classes with blocks

Since Blocks are objective C objects that gets pushed onto the stack…

A Block is the one instance of an Objective-C object that starts on the stack. While you can happily collect together a bunch of Blocks in one of the Foundation provided collection classes (NSArray, NSDictionary, or NSSet), make sure you copy the Block before you do!

The last thing you want is a stack based object to end up in an autorelease pool….

The reason why Blocks start on the stack is because it is really really fast. Orders of magnitude faster than allocating a chunk of memory for each Block.

other ref-

http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap

Block basics

reference
http://stackoverflow.com/questions/22996536/resolving-retain-cycles-is-there-really-a-reason-to-add-strong-strongself-wh?rq=1
http://rypress.com/tutorials/objective-c/blocks

http://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html

demo xCode 7.3

How To Declare

Interface: We have the return type. Then block name. Then the parameters.

Then a equals sign, which leads to our declaration of the block. In the declaration of the block, be sure to name your parameters.

non-local variables are variables defined in the block’s enclosing lexical scope, but outside the block itself.

non-local variable are copied and stored with the block as const variable, which means they are read-only.

In other words, it creates “const” copy of any local variables that is referenced inside its scope.

Global Blocks – not referencing any non-local variables

With no references to the surrounding scope, clang configures the Block_literal as a global block instead.

For example,

If you’re familiar with how Objective-C objects are declared, the isa field in the Block_literal above should be familiar — blocks are Objective-C objects.

As you see, it does not reference any non-local variables. Thus, the compiler creates it as a global block:

global_block

This causes the block to appear in a fixed global location instead of on the local stack.

The implication of this is that global blocks are never actually copied or disposed, even if you invoke the functions to do so. This optimization is possible because without any references to the surrounding scope, no part of the block (neither its code nor its Block_literal) will ever change — it becomes a shared constant value.

Malloc Blocks – __strong block definitions

The block object was retained by the whisper variable. The strong sends a retain to the block. When a block is retained, it invokes a copy on it.

block implementation detail:

Thus, the block object was moved from stack to heap by this _Block_copy. But note that there is only still 1 copy of the block. It simply increases the retain count of the block.

malloc_block

Stack Blocks – __weak block definitions

http://stackoverflow.com/questions/25794306/could-you-help-me-to-understand-block-types-when-added-to-containers-nsdictiona

http://stackoverflow.com/questions/19227982/using-block-and-weak

Marking it as __weak causes the whisper variable to NOT retain the block object.
Thus, the block starts off being allocated on the local stack, and it stays there. Since there is no __strong to retain it, and thus, no copy.

therefore, a weak block variable on a block object keeps the block object on the local stack.

stack_block

If you copy an NSStackBlock, it will return an NSMallocBlock (indicating its changed allocation location).

A block keeps it’s own array of its non-local variables via deep copy

example:

So as you can see, the non-local variable make gets copied inside of the block getFullCarName. If you try to modify make inside of the block getFullCarName, you will see a compiler error.

Notice how later, outside of the block, we change the variable make to “BMW”. However, its a deep copy, this change takes place at the outside of the closure. Hence the original make variable (outside of the closure) is BMW. The copy inside the block, the make is still Honda. We see this happening by passing @”Civic” into getFullCarName(…).

You can make non-local changeable by using __block to use them as reference

Freezing non-local variables as constant values is a safe default behavior
in that it prevents you from accidentally changing them from within the block;
however, there are occasions when this is NOT desirable.

You can override the const copy behavior by declaring a non-local variable with the __block storage modifier:

This tells the block to capture the variable by reference, whereas if you didn’t have __block, it would capture it by deep copy.

When the block captures the variable by reference, its like creating a direct link between the variable outside the block and the one inside the block.
You can now assign a new value to make from outside the block, and it will be reflected in the block, and vice versa.

So now, you are referencing the same variable outside and inside the block. Whereas before, you have 2 deep copies of the variable depending on whether you are outside or inside of the closure.

Each block has its own copy of the non-local variables

In the example below, if we call existingBlock or vv twice, you will see that the non-blocking variables that they copy will have the same address. Their local variables, however, are all different throughout the calls. That’s because for the local variables of the block, they just go on the stack. Where as the outside scope’s variable are all copied….in an array for that particular block.

But what about Object allocations

As show in the code above, we have a block called vv. vv calls existingBlock block.
Then, say we have an object allocation outside of the block existingBlock at the highest scope at foo function.

We have 2 parts:

1) the reference ptrToStrObj gets pushed onto the local stack,
with address say: 0x7fff5fbff708

2) and the object that’s allocated on the heap, pointed to by reference ptrToStrObj. The object has address say: 0x100102450

block-1


LOCAL – address of POINTER ptrToStrObj……0x7fff5fbff708
LOCAL – address of NSString object on heap……0x100102450

The ptrToStrObj variable is a non-local variable, which means it defined in the block’s enclosing lexical scope, but OUTSIDE of the block itself. It is deep copied inside of the block.

We display the address of the the reference ptrToStrObj inside of the block existingBlock, which then shows:


———-existingBlock START ——
existingBlock – address of POINTER ptrToStrObj……0x1020001c0
existingBlock – address of OBJECT……0x100102450
existingBlock – ricky tsao, dob 6680
———-existingBlock END ——

As you can see, the address of the object on the heap remains at 0x100102450.
But the pointer of the reference ptrToStrObj has changed from 0x7fff5fbff708 to 0x1020001c0.

That is proof that the block made a deep copy of the non-local variable reference ptrToStrObj for itself.

Furthermore, if you try to modify ptrToStrObj, it will throw an error:

change-nonlocal-block

After calling existingBlock(), we move on to the next line:

changing content of string object
vv – address of POINTER ptrToStrObj……0x102000248
vv – address of OBJECT……0x100102450
vv – HA DO KEN!ao, dob 6680
———-vv END ——

Keep in mind that we are now back in bloc vv.

As you can see, the address of the object in the heap remains the same at 0x100102450.
However, the pointer address changed to 0x102000248. This means that this block vv has its own DEEP COPY of the non-local variable ptrToStrObj.

Thus,

foo’s ptrToStrObj is 0x7fff5fbff708
existingBlock’s ptrToStrObj is 0x1020001c0
vv’s ptrToStrObj is 0x102000248

In much deeper details, each block has an non-local variable array list. That’s where it keeps its list of non-local variables. As we can see in the picture vv block and existingBlock each have an array of non-local variables.

The first item in their array is reference ptrToStrObj. ptrToStrObj points to the object in the heap, which never changes as we can see that the addresses all match.

However the address of the references are different, because each block has their own DEEP COPY of the reference.

block-2

Finally, let’s see what happens inside of a GCD block:

THREAD 2 start
———-vv START ——
———-existingBlock START ——
existingBlock – address of POINTER ptrToStrObj……0x1020001c0
existingBlock – address of OBJECT……0x100102450
existingBlock – HA DO KEN!ao, dob 6680
———-existingBlock END ——
changing content of string object
vv – address of POINTER ptrToStrObj……0x102000248
existingBlock – address of OBJECT……0x100102450
existingBlock – HA DO KEN!N!ao, dob 6680
———-vv END ——
in dispatch_async block – address of POINTER ptrToStrObj……0x100500048
existingBlock – HA DO KEN!N!ao, dob 6680
existingBlock – address of OBJECT……0x100102450
THREAD 2 done

As you can see the object in the heap as address 0x100102450 for all blocks

existingBlock’s ptrToStrObj has 0x1020001c0
vv’s ptrToStrObj has 0x102000248
GCD’s ptrToStrObj has 0x100500048

Hence, as you can see, GCD’s block, like any other blocks, also have its own non-local variable list, and DEEP COPIES the non-local variable reference ptrToStrObj for itself.

Code

output:

LOCAL – address of POINTER ptrToStrObj……0x7fff5fbff7e8
LOCAL – address of NSString object on heap……0x100211f00
Stack: &x: 0x7fff5fbff7f8, 1
Stack: &x: 0x7fff5fbff7f4, 2
——- on main thread ——-
———-vv START ——
existingBlock – address of POINTER ptrToStrObj……0x1001001e0
existingBlock – address of OBJECT……0x100211f00
existingBlock – ricky tsao, dob 6680
———-existingBlock END ——
changing content of string object
vv – address of POINTER ptrToStrObj……0x100300378
existingBlock – address of OBJECT……0x100211f00
existingBlock – HA DO KEN!ao, dob 6680
———-vv END ——
THREAD 2 start
———-vv START ——
———-existingBlock START ——
existingBlock – address of POINTER ptrToStrObj……0x1001001e0
existingBlock – address of OBJECT……0x100211f00
existingBlock – HA DO KEN!ao, dob 6680
———-existingBlock END ——
changing content of string object
vv – address of POINTER ptrToStrObj……0x100300378
existingBlock – address of OBJECT……0x100211f00
existingBlock – HA DO KEN!N!ao, dob 6680
———-vv END ——
in dispatch_async block – address of POINTER ptrToStrObj……0x100300168
existingBlock – HA DO KEN!N!ao, dob 6680
existingBlock – address of OBJECT……0x100211f00
THREAD 2 done

More Examples

GCD: dispatch_async

Contrary to what’s usually believed, dispatch_async per se will NOT cause a retain cycle

Here, the closure has a strong reference to self, but the instance of the class (self) does not have any strong reference to the closure, so as soon as the closure ends, it will be released, and so no cycle will be created. However, sometimes it’s (incorrectly) assumed that this situation will lead to a retain cycle.

Syntax

Blocks are declared like so:

..and used like so:

This example declares a variable called simpleBlock to refer to a block that takes no arguments and doesn’t return a value

You can also combine the variable assignment, and definition:

Another Example

The (void (^)(void)) specifies that the parameter is a block that doesn’t take any arguments or return any values. The implementation of the method can invoke the block in the usual way:

Method parameters that expect a block with one or more arguments are specified in the same way as with a block variable:

it expects a block that does not return anything. But takes in double as the first 2 parameters.

calling method on a nil object

A message sent to a nil object is perfectly acceptable in Objective-C, it’s treated as a no-op. There is no way to flag it as an error because it’s not an error, in fact it can be a very useful feature of the language.

From the docs:

Sending Messages to nil

In Objective-C, it is valid to send a message to nil—it simply has no effect at runtime. There are several patterns in Cocoa that take advantage of this fact. The value returned from a message to nil may also be valid:

If the method returns an object, then a message sent to nil returns 0 (nil), for example:

Person *motherInLaw = [[aPerson spouse] mother];

If aPerson’s spouse is nil, then mother is sent to nil and the method returns nil.

If the method returns any pointer type, any integer scalar of size less than or equal to sizeof(void*), a float, a double, a long double, or a long long, then a message sent to nil returns 0.

If the method returns a struct, as defined by the Mac OS X ABI Function Call Guide to be returned in registers, then a message sent to nil returns 0.0 for every field in the data structure. Other struct data types will not be filled with zeros.

If the method returns anything other than the aforementioned value types the return value of a message sent to nil is undefined.

pointers (C) vs references (Java)

ref – http://programmers.stackexchange.com/questions/141834/how-is-a-java-reference-different-from-a-c-pointer

References might be implemented by storing the address. Usually Java references will be implemented as pointers, but that’s not required by the specification. They may be using an additional layer of indirection to enable easier garbage collection. But in the end it will (almost always) boil down to (C-style) pointers being involved in the implementation of (Java-style) references.

You can’t do pointer arithmetic with references. The most important difference between a pointer in C and a reference in Java is that you can’t actually get to (and manipulate) the underlying value of a reference in Java. In other words: you can’t do pointer arithmetic.

In C you can add something to a pointer (i.e. the address) or substract something to point to things that are “nearby” or point to places that are at any place.

In Java, a reference points to one thing and that thing only. You can make a variable hold a different reference, but you can’t just ask it to point to “the thing after the original thing”.

References are strongly typed. Another difference is that the type of a reference is much more strictly controlled in Java than the type of a pointer is in C. In C you can have an int* and cast it to a char* and just re-interpret the memory at that location. That re-interpretation doesn’t work in Java: you can only interpret the object at the other end of the reference as something that it already is (i.e. you can cast a Object reference to String reference only if the object pointed to is actually a String).

Those differences make C pointers more powerful, but also more dangerous. Both of those possibilities (pointer arithmetic and re-interpreting the values being pointed to) add flexibility to C and are the source of some of the power of the language. But they are also big sources of problems, because if used incorrectly they can easily break assumptions that your code is built around. And it’s pretty easy to use them incorrectly.

dynamic binding vs static binding

ref -http://www.tutorialspoint.com/objective_c/objective_c_dynamic_binding.htm

Dynamic binding is determining the method to invoke at runtime instead of at compile time. Dynamic binding is also referred to as late binding.

In Objective-C, all methods are resolved dynamically at runtime, due to having every class must derive from NSObject. The exact code executed is determined by both the method name (the selector) and the receiving object. On the other hands, functions such as NSLog or abs, fabs, etc are statically bound. They are determined during compile time.

Dynamic binding enables polymorphism. For example, consider a collection of objects including Rectangle and Square. Each object has its own implementation of a printArea method.

In the following code fragment, the actual code that should be executed by the expression [anObject printArea] is determined at runtime. The runtime system uses the selector for the method run to identify the appropriate method in whatever class of anObject turns out to be.

Parent class – Shape

Child class Square

Child class – Rectangle

Main

Now when we compile and run the program, we will get the following result.

2013-09-28 07:42:29.821 demo[4916] The area of square is 100.000000
2013-09-28 07:42:29.821 demo[4916] The area of Rectangle is 50.000000

The parent class pointer will know which method to execute because it will dynamically bind the correct method to the object at hand. Note that we can also do it with

because id is a generic pointer.

Namely, ff you have a reference that’s of parent type at compile type, you can assign a child type to it at runtime. The behavior of the reference will change to the appropriate type at runtime. A virtual table lookup will be done to let the runtime figure out what the dynamic type is.

Another exaplantion:

Dynamic binding – This is a step beyond late binding where it is left to runtime to determine if the referenced item exists. A simple example in Objective-C:

Static Binding

Static, compile time binding is easy. There’s no polymorphism involved. You know the type of the object when you write and compile and run the code. Sometimes a dog is just a dog.

Static binding: is where the item being referred to is determined at compile time. In (Objective-)C(++) a call to a function is statically bound; for example the library functions fabs and NSLog.

Also references to variables are static in these languages; which variable is being referenced is determined completely at compile time. Static binding cannot fail at runtime, it is a compile time error to fail to determine what a statically bound reference refers to.

Core Data part 1 and 2 – data model and data stack

DEMO PROJECT

Create a Single Project

name it “CoreDataTut”

We’re going to do everything by scratch so do not check the Core Data box. Leave it blank.

Generate a xcdatamodeld file

Once the project is generated, look at your list view on the left side. We need a .xcdatamodeld file, which represents the model diagram of our entities. The reason why is because core data code need to use a .xcdatamodeld to initialize a Managed object Model, which it uses to save state and data.


See how to create a data model here

In our core data stack, we actually load this file into an NSManagedObjectModel object.
Make sure that the name of your data model . xcdatamodeld file matches that of the name you use in your code. We do this by using global #define as noted in the code below.

The core data stack

First we make a singleton object out of Core data’s basics by creating a singleton class that houses

  • NSManagedObjectContext
  • NSManagedObjectModel
  • NSPersistentStoreCoordinator

From a picture perspective, core data’s basic parts are connected like this:

basic_core_data_diagram

Create the source file:

coredata_create_corestack

Click on Cocoa Touch Class, and input “THCoreDataStack”. The subclass should be “NSObject”.

coredata_name_corestack

THCoreDataStack.h source

THCoreDataStack.m

Managed Object Model

The lazy loading and getter method of our MOM.

http://stackoverflow.com/questions/10579767/why-the-extension-is-momd-but-not-xcdatamodel-when-search-the-path-for-the-m

The mom and momd files are compiled versions of xcdatamodel and xcdatamodeld files…so here we’re just saying that we need to allocate a NSManagedObjectModel object and init with the compiled versions of our xcdatamodeld files.

Basic lazy loading of the PSC, and its getter. When creating the PSC, we use a #define macro for the sql’s file name.

Managed Object Context – scratch pad for DB changes

This MOC is basically a scratch pad for database changes. Later, when you save context, it will be reflected to the Persistent Store Coordinator, and thus, the database.
We have basic lazy loading and get methods for the MOC.

Saving the Context

This method is called right after an Object is returned from the MOC designated to be inserted or changed.

That way the MOC’s changes are safely saved.

lazy loading pattern using property and synthesize

Protected Methods, Private, and Public (obj c)

download demo

Protected Methods

Base.h

Note, that private attributes are accessible only by the class that declared it. No others can access it. Hence, in our Base class, it declares private attributes and freely uses it. However, in main, only the public attributes appears and can be accessed.

Base.m

Public means anyone can access these variables or methods. This includes the object themselves, as well as other objects.

When you create the Base object, and try to access the public attributes, you will see all the public members and methods we’ve declared.

public-access

Private access from other objects

You will not be able to see the private members and methods because you are not allowed access to them. Only the Base class that declared those private attributes can access them.

main.m

Derived Classes

Say we derive a child class from Base.

Child1.m

When you create a child class and derive it from a base class, you can only use the parent class’ public attributes. You cannot use its private attributes.

In other languages, we’d usually protected. Which is basically private + the ability to let child classes access your private attributes.

Protected Members (iVars)

Base.h

Base.m

Child.h

Child.m

Main

So basically, Child derives from Base. It access Base’s protected string, changes its content, and logs it. Thus we see


Child.m – This child likes to laugh.. haha!

Which is what we set in the Child class. This is how we use protected variables. However, if we were to use properties, it gets a little bit complicated.

Protected Variables (property)

First, we add properties get/set to our protectedString by doing:

Then synthesize it to generate auto-get/set methods

Finally, we implement a custom set method so that we can see how it all works. Put the custom method in your Base.m file:
Base.m

Be careful you don’t use self.protectedString because by definition, you’ll go into an infinite loop: You keep accessing your own set method.

In both Child and Base’s init, do self.protectedString. That way, we use and make our properties take into effect.

output:

—– BASE INIT start——
Base.m – iVar protectedString set

Base.m [Calling class Child] – setProtectedString <-- Base.m - protectedString was: (null) Base.m [Calling class Child] - setProtectedString -->

—– BASE INIT end ——
—– CHILD INIT start ——
Uses iVar protectedString

Base.m [Calling class Child] – setProtectedString <-- Base.m - protectedString was: Base set protectedString Base.m [Calling class Child] - setProtectedString -->

—– CHILD INIT end ——
Child.m – This child likes to laugh.. haha!

You will see that Child object in main does its init, which uses Base class’s init. Base class’s init simply uses the self.protectedString property, which calls the custom set method setProtectedString.

The custom set method sees that the iVar protectedString was null, then it gets set to “Base set protectedString”.

The Child’s init runs and using the property self.protectedString. It sees that it as a custom setProtectedString method in its Parent class, and uses that to set the iVar protectedString to a new value.

Over-riding Propert’s custom method

If your Child class wants to use its own custom method, then over-ride the Base class’s custom set method setProtectedString.

Child.m

output:


Hello, World!
—– BASE INIT start——
Base.m – iVar protectedString set

Child.m [Calling class Child] – setProtectedString <-- Child.m - protectedString was: (null) Child.m [Calling class Child] - setProtectedString -->
—– BASE INIT end ——

—– CHILD INIT start ——
Child: Uses iVar protectedString

Child.m [Calling class Child] – setProtectedString <-- Child.m - protectedString was: Base set protectedString Child.m [Calling class Child] - setProtectedString -->

—– CHILD INIT end ——
Child.m – This child likes to laugh.. haha!

Take heed that in Base’s init method, the self.protectedString accesses the custom set method in Child as shown in the output. This is because Child over-rode its parent class’s setProtectedString method.

The attribute protectedString still belongs to the Base class. The property generated its get/set in the Base class. But the Child class over-rode the set method, and thus, that’s why in Base’s init, we access the set method in Child.

Protected Methods

we use category in a dedicated header file

Base+Protected.h

Then, import the Base+Protected.h category file into your Base class. Make sure you implement the protected method.

Note that IF we have not imported Base+Protected.h, “protectedMethod” method would be a private method.

Before, we can access parent’s public. If you try to access Base’s protectedMethod, it will see it as trying to access the private of the Base class, and throw an error:

protected-cant-access

You need to #import “Base+Protected.h”, then you will be able to access the protected method which was attached to the Parent class via Category.

Thus, you just created protected access in objective c

The import of the category .h file acts as an access to private attributes mechanism. In obj c, we simply use it to give us protected-access behavior.

When you run it, you will see that the Child class calls the Base class.

Without a protected category, there would be no way for subclasses to access this method.

Keep in mind that protected attributes are really meant for child classes to use. It is still private in nature, and should not let global objects access them. They should only be accessed by its parent and anyone who is their children.

Keep in mind that accessing private and over-riding are two different things

In this section, we talk about how to have child objects access parent’s private methods via protected mechanism. However, child objects CAN accidently OVER-RIDE parent private methods:

Private methods in Objective C are semi private